I have an array of time that I get from the database and pass it to the javascript.when I alert the array variable I get the array of times(in my case 2 different times say 12:00 and 14:30),let the array be newdate.
In the javascript I also take in the another time say date=(12:00) I want to compare both the timings.both the values in newdate compare with date.
How to do it?
I tried the following
var newdate = new Array();
newdate = $('#newdate').val();
for(i=0;i<newdate.length;i++) {
alert(newdate[i]);
}
if (newdate >= date) {
alert("enable");
}
else {
alert("disbale");
}
when I ALERT the above I get 1,2,:,0,0 which is wrong,I want 12:00
Problem
Consider the following samples :
var string = '12:30';
for (var i = 0; i < string.length; i++) {
console.log(string[i]); // will print each character separately
}
var array = ['12:30']; // array of strings
for (var i = 0; i < array.length; i++) {
console.log(array[i]); // will print "12:30"
}
In the first case, replacing '12:30' with ['1', '2', ':', '3', '0'] will give the same result, in other words, looping through a string is like looping through an array of characters. Knowing that, let's return back to your own code :
// newdate is an empty array -> []
var newdate = new Array();
// ... then newdate is overwritten with a string -> "12:00"
newdate = $('#newdate').val();
// ... then newdate is traversed -> ["1", "2", ":", "0", "0"]
Solution
Here is how you could test a time against a collection :
var temp, item, gte;
var time = '12:15';
var collection = ['12:45', '12:00', '12:15', '12:30', '13:00', '11:00'];
var temp = time.split(':');
for (var i = 0; i < collection.length; i++) {
item = collection[i].split(':');
gte = +temp[0] >= +item[0];
if (gte) gte = +temp[1] >= +item[1];
// if (gte) gte = +temp[2] >= +item[2]; // uncomment to check seconds
if (gte) alert(time + ' >= item #' + i);
}
The above code will alert three times :
12:15 >= item #1
12:15 >= item #2
12:15 >= item #5
Going further
Reduces the collection to times that pass the function's test :
function filter(collection, fn) {
var i = 0,
l = collection.length,
result = [],
item;
for (; i < l; i++) {
item = collection[i];
if (fn(item, i)) result.push(item);
}
return result;
}
Returns a test function for times greater than or equal to the passed one :
function gte(time) {
time = time.split(':');
return function (item) {
item = item.split(':');
return +time[0] < +item[0] || (
+time[0] === +item[0] && +time[1] <= +item[1]
);
};
}
Returns a test function for times lower than or equal to the passed one :
function lte(time) {
time = time.split(':');
return function (item) {
item = item.split(':');
return +time[0] >= +item[0] && +time[1] >= +item[1];
};
}
Usage examples :
var collection = ['12:45', '12:00', '12:15', '12:30', '13:00', '11:00'];
var gteNoon = filter(collection, gte('12:00'));
var lteNoon = filter(collection, lte('12:00'));
var aroundNoon = filter(collection, function (time) {
return time.slice(0, 2) === '12';
});
gteNoon; // ["12:45", "12:00", "12:15", "12:30", "13:00"]
lteNoon; // ["12:00", "11:00"]
aroundNoon; // ["12:45", "12:00", "12:15", "12:30"]
Related
I have the following json file
[{"id":5,"num":"n61","mov_date":"2019-02-01T00:00:00","orders":19},
{"id":5,"num":"n61","mov_date":"2019-02-05T00:00:00","orders":12},
{"id":5,"num":"n61","mov_date":"2019-02-08T00:00:00","orders":5},
{"id":5,"num":"n61","mov_date":"2019-02-11T00:00:00","orders":7}]
I want to add new items using JavaScript, jquery, to end up with
[{"id":5,"num":"n61","mov_date":"2019-02-01T00:00:00","orders":19},
{"id":5,"num":"n61","mov_date":"2019-02-02T00:00:00","orders":0},
{"id":5,"num":"n61","mov_date":"2019-02-03T00:00:00","orders":0},
{"id":5,"num":"n61","mov_date":"2019-02-04T00:00:00","orders":0},
{"id":5,"num":"n61","mov_date":"2019-02-05T00:00:00","orders":12},
{"id":5,"num":"n61","mov_date":"2019-02-06T00:00:00","orders":0},
{"id":5,"num":"n61","mov_date":"2019-02-07T00:00:00","orders":0},
{"id":5,"num":"n61","mov_date":"2019-02-08T00:00:00","orders":5},
{"id":5,"num":"n61","mov_date":"2019-02-09T00:00:00","orders":0},
{"id":5,"num":"n61","mov_date":"2019-02-10T00:00:00","orders":0},
{"id":5,"num":"n61","mov_date":"2019-02-11T00:00:00","orders":7}]
maybe by calculating the number of missed items between dates, or just calculating the diff between the numbers represents the day i.e: "2019-02-01T00:00:00" and "2019-02-05T00:00:00" then add 3 items?
var items = [
{"id":5,"num":"n61","mov_date":"2019-02-01T00:00:00","orders":19},
{"id":5,"num":"n61","mov_date":"2019-02-05T00:00:00","orders":12},
{"id":5,"num":"n61","mov_date":"2019-02-08T00:00:00","orders":5},
{"id":5,"num":"n61","mov_date":"2019-02-11T00:00:00","orders":7}
]
var newItems = []
for(var i = 0; i < items.length; i++){
newItems.push(items[i])
var currentDay = moment(items[i].mov_date)
var nextDay = currentDay.add(1, 'days');
if(typeof items[i+1] !== 'undefined'){
var diff = moment(items[i+1].mov_date).diff(currentDay, 'days')
for(var j = 1; j <= diff; j++){
var newItem = JSON.parse(JSON.stringify(items[i]))
newItem.mov_date = moment(items[i].mov_date).add(j, 'days').utc(false).format();
newItem.orders = 0
newItems.push(newItem)
}
}
}
console.log(newItems)
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>
Check also this one that uses reduce() preserving all the props(including id) and only resetting orders and setting correct mov_date in between.
var items = [{
"id": 5,
"num": "n61",
"mov_date": "2019-02-01T00:00:00",
"orders": 19
},
{
"id": 5,
"num": "n61",
"mov_date": "2019-02-05T00:00:00",
"orders": 12
},
{
"id": 5,
"num": "n61",
"mov_date": "2019-02-08T00:00:00",
"orders": 5
},
{
"id": 5,
"num": "n61",
"mov_date": "2019-02-11T00:00:00",
"orders": 7
}
]
const newItems = items.reduce((acc, next) => {
// first run with early return
if (!acc.length) {
return [...acc, next]
}
// taking the recent item, to preserve the id and other props
const prevItem = acc[acc.length - 1];
// getting diff in days - 1
const days = moment.utc(next.mov_date).diff(moment.utc(prevItem.mov_date), 'days') - 1;
// [...Array] is a trick to get mappable arrays without array holes,
// but with initialized undefined values,
// so we can get the index during map
const inBetweenValues = [...Array(days)].map((_, dayIndex) => {
return {
...prevItem,
orders: 0,
mov_date: moment.utc(prevItem.mov_date).add(dayIndex + 1, 'days').format()
};
});
// merging it all, and moving to the next loop
return [...acc, ...inBetweenValues, next];
}, [])
console.log(newItems);
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>
You could use a Date object which you increment using its setDate method, and which you render to string with toJSON. Then when the date string matches the next entry, you copy it, otherwise you duplicate it with orders: 0:
const data = [{"id":5,"num":"n61","mov_date":"2019-02-01T00:00:00","orders":19},{"id":5,"num":"n61","mov_date":"2019-02-05T00:00:00","orders":12},{"id":5,"num":"n61","mov_date":"2019-02-08T00:00:00","orders":5},{"id":5,"num":"n61","mov_date":"2019-02-11T00:00:00","orders":7}];
const end = new Date(data[data.length-1].mov_date + "Z");
const result = [];
for (let dt = new Date(data[0].mov_date+"Z"), i = 0; dt <= end; dt.setUTCDate(dt.getUTCDate()+1)) {
result.push({...data[i], ...(dt.toJSON().slice(0,19) === data[i].mov_date ? (i++, {}) : { orders: 0 })});
}
console.log(result);
Here is an algorithm that will do That for you. I used
Convert JS date time to MySQL datetime for date conversion.
function twoDigits(d) {
if(0 <= d && d < 10) return "0" + d.toString();
if(-10 < d && d < 0) return "-0" + (-1*d).toString();
return d.toString();
}
function toMysqlFormat() {
return this.getUTCFullYear() + "-" + twoDigits(1 + this.getUTCMonth()) + "-" + twoDigits(this.getUTCDate()) + "T" + twoDigits(this.getUTCHours()) + ":" + twoDigits(this.getUTCMinutes()) + ":" + twoDigits(this.getUTCSeconds());
};
var prev = 0;
for( var x = 1; x < obj.length; x++ ){
if( !obj[x -1].mov_date ){
continue;
}
var tx = Date.parse( obj[x-1].mov_date );
var diff = ( Date.parse(obj[x].mov_date ) - tx ) / (1000*24*60*60);
for( var y = 1; y < diff; y++ ){
obj.splice( x - 1 + y,0, { "id" : 5, "num" : "n61", "mov_date" : toMysqlFormat.bind( new Date( tx + ( y*1000*24*60*60) ) )(), "orders" : 0} );
}
x += diff - 1;
}
for( var x = 0; x < obj.length; x++ ){
console.log( JSON.stringify( obj[x] ) );
}
/* Result :
/* {"id":5,"num":"n61","mov_date":"2019-02-01T00:00:00","orders":19} */
/* {"id":5,"num":"n61","mov_date":"2019-02-02T00:00:00","orders":0} */
/* {"id":5,"num":"n61","mov_date":"2019-02-03T00:00:00","orders":0} */
/* {"id":5,"num":"n61","mov_date":"2019-02-04T00:00:00","orders":0} */
/* {"id":5,"num":"n61","mov_date":"2019-02-05T00:00:00","orders":12} */
/* {"id":5,"num":"n61","mov_date":"2019-02-06T00:00:00","orders":0} */
/* {"id":5,"num":"n61","mov_date":"2019-02-07T00:00:00","orders":0} */
/* {"id":5,"num":"n61","mov_date":"2019-02-08T00:00:00","orders":5} */
/* {"id":5,"num":"n61","mov_date":"2019-02-09T00:00:00","orders":0} */
/* {"id":5,"num":"n61","mov_date":"2019-02-10T00:00:00","orders":0} */
/* {"id":5,"num":"n61","mov_date":"2019-02-11T00:00:00","orders":7} */
*/
I am plotting a graph using d3.js by loading an external .CSV file.
The code i have so far works fine with a small amount of data but when i load a larger file with thousands of lines then it kills the page.
The data has a usage column which is a value for every 30 mins throughout the day, which will go on over several months.
See Plunker example.
var avgClientArr = [];
var dateArr = [];
var dateGroupArr = [];
function csvParseClient() {
d3.xhr('client.csv').get(function(err, response) {
var dirtyCSV = response.responseText;
var initialClientKeys = /TYPE,DATE,START TIME,END TIME,USAGE,UNITS,NOTES/i;
var newClientKeys = "TYPE,x,startTime,endTime,y,UNITS,NOTES";
var csvDataClient = dirtyCSV.replace(initialClientKeys, newClientKeys);
var validData = csvDataClient.substr(csvDataClient.indexOf(newClientKeys));
var csvData = d3.csv.parse(validData);
csvData.customForEach(function(val, i) {
// filter data
//var keep = ['x', 'startTime', 'endTime', 'UNITS', 'y'];
//for (var key in val[i]) {
// if (keep.indexOf(key) === -1) {
// delete val[i][key];
// }
//}
// parse data
var date = val.x;
var usage = val.y;
var startTime = val.startTime;
var endTime = val.endTime;
var x = new Date(date);
var y = parseFloat(usage);
dateArr.push({
"date": x,
"usage": y
})
dateGroupArr = groupBy(dateArr, 'date');
})
console.log(dateGroupArr);
var objDates = objectValues(dateGroupArr);
objDates.customForEach(function(f) {
var avg = f.reduce(function(a, b) {
return a + b.usage;
}, 0) / f.length;
var date = f.reduce(function(a, b) {
return new Date(b.date);
}, 0);
avgClientArr.push({
"x": date,
"y": avg
})
})
//console.log("avgClientArr", avgClientArr);
document.getElementById('arrayDiv').innerHTML = '<pre>' + JSON.stringify(avgClientArr, null, 4) + '</pre>';
})
}
function groupBy(arr, key) {
var reducer = (grouped, item) => {
var group_value = item[key]
if (!grouped[group_value]) {
grouped[group_value] = []
}
grouped[group_value].push(item)
return grouped
}
return arr.reduce(reducer, {})
}
function objectValues(object) {
var values = []
for (var property in object) {
if (object.hasOwnProperty(property)) {
values.push(object[property])
}
}
return values
}
function foreach(fn) {
var arr = this;
var len = arr.length;
for (var i = 0; i < len; ++i) {
fn(arr[i], i);
}
}
Object.defineProperty(Array.prototype, 'customForEach', {
enumerable: false,
value: foreach
});
var t0 = performance.now();
csvParseClient();
var t1 = performance.now();
console.log("Call csvParseClient() " + (t1 - t0) + " milliseconds.");
What i need to happen
I need the average value of usage for the whole day returned as y and the date for that day returned as x for each day.
The slow process i have
Start the loop from a specified line in the CSV file as there is unwanted data on the first few lines.
Group unique date and store each usage value for that date in an object.
Average the usage values for each date.
Output an array of objects with property x being the date and y being the average usage value.
If you can give me any help on how to make this run faster that would be great!
I solved this by using the d3 nest() and rollup() functions, its simple and really fast.
d3.nest()
.key(function(d) {
return d.x;
})
.rollup(function(d) {
var avg = d3.mean(d, function(g) {return g.y; });
return avg;
}).entries(dateArr);
I have an array which looks like:
var data = [{"year":[1981],"weight":[3]},
{"year":[1982],"weight":[4]},
{"year":[1985],"weight":[7]}]
My data series starts with year 1980 and ends with year 1986. My task is to input all missing values into the array; in my case the final array should be:
var data = [{"year":[1980],"weight":[0]},
{"year":[1981],"weight":[3]},
{"year":[1982],"weight":[4]},
{"year":[1983],"weight":[0]},
{"year":[1984],"weight":[0]},
{"year":[1985],"weight":[7]},
{"year":[1986],"weight":[0]}]
I implemented this task in two steps. First I created an empty array with length of seven elements (for years 1980 - 1986) and initialize each element with value {"year": $CURRENT_YEAR, "weight": 0}. Then I loop through data array, find index of current year in the empty array and replace year and weight fields with current values. My code is pasted below.
I wonder if the code could be rewritten in a more elegant way.
// Create empty array
var my_array = []
var length = 7
// 1st step
year = 1980
for (var i = 0; i < length; i++) {
my_array.push({"year": year, "weight": 0});
year++
}
// 2nd step
for (var j = 0; j < data.length; j++) {
curr_year = data[j]["year"][0];
curr_weight = data[j]["weight"][0]
var index = my_array.findIndex(function(item, i) {return item.year === curr_year})
my_array[index] = {"year": curr_year, "weight": curr_weight}
}
It's best to do this job by .map() Besides if you have a large input array it might be wise to set up a hash (lut) in the first place such as;
var data = [{"year":[1981],"weight":[3]},
{"year":[1982],"weight":[4]},
{"year":[1985],"weight":[7]}],
lut = data.reduce((p,c) => p[c.year[0]] ? p : (p[c.year[0]] = c, p), {});
range = [1980,1986],
result = Array(range[1]-range[0] + 1).fill()
.map((_,i) => lut[i+range[0]] ? lut[i+range[0]] : {year: [i+range[0]], weight: [0]});
console.log(result);
You can combine the 2 loops and do both steps in one loop
// Create empty array
var my_array = []
var length = 7
year = 1980
for (var i = 0; i < length; i++) {
// check if there is data for the year
var index = data.findIndex(function(item, i) {return item.year === year});
if(index > -1){ //if there is data, use it
my_array.push({"year": data[index]["year"][0], "weight": data[index]["weight"][0]});
}else{ //put in default data
my_array.push({"year": year, "weight": 0});
}
year++;
}
Find index of element in array each time is bad performance for large data. I can suggest the following algorithm:
// Create empty object and fill it with values where keys are years
var years = {};
data.forEach(item => {
years[item.year[0]] = item.weight[0];
});
// Result array with all years
var result = [];
var startYear = 1980;
var endYear = 1986;
// Generate our result array
for (var i = startYear; i <= endYear; i++) {
// If property for given year (i) exists in "years" object then add it to "result" array
// in other case add default object with weight 0
var o = years[i] ? { year: [i], weight: [years[i]] } : { year: [i], weight: [0] };
result.push(o);
}
You could do this with just find() and while loop.
var data = [{"year":[1981],"weight":[3]},{"year":[1982],"weight":[4]},{"year":[1985],"weight":[7]}];
var i = 1980;
var result = [];
while(i <= 1986) {
var find = data.find(e => e.year[0] == i);
(find) ? result.push(find) : result.push({year: [i], weight: [0]});
i++;
}
console.log(result)
You could also first use map() to get array of years and then use while loop with indexOf().
var data = [{"year":[1981],"weight":[3]},{"year":[1982],"weight":[4]},{"year":[1985],"weight":[7]}];
var i = 1980;
var result = [];
var years = data.map(e => e.year[0]);
while(i <= 1986) {
var ind = years.indexOf(i);
(ind != -1) ? result.push(data[ind]) : result.push({year: [i], weight: [0]});
i++;
}
console.log(result)
I have an array of Date() objects in javascript and I want to count the number of events on each day.
Here is an example:
What I have is:
Array [ Date 2014-12-04T10:30:20.000Z, Date 2014-12-05T11:04:58.056Z, Date 2014-12-05T11:04:58.056Z, Date 2014-12-05T11:04:58.056Z ]
What I want is:
Array [{date: '2014-12-04', counts: 1}, {date: '2014-12-05', counts: 3}]
Thanks a lot!
Max
Basic answer:
var arr = [], // fill it with array with your data
results = {}, rarr = [], i, date;
for (i=0; i<arr.length; i++) {
// get the date
date = [arr[i].getFullYear(),arr[i].getMonth(),arr[i].getDate()].join("-");
results[date] = results[date] || 0;
results[date]++;
}
// you can always convert it into an array of objects, if you must
for (i in results) {
if (results.hasOwnProperty(i)) {
rarr.push({date:i,counts:results[i]});
}
}
These can be made much easier with lodash functions, and Array.forEach() in ES5
You much better off having a simple object with the keys as the date and the value as the count. I've added a simple pad function that prefixes a zero where the number is a single digit as per your output requirements.
function pad(n) {
return n.toString().length == 1 ? '0' + n : n;
}
function getCount(arr) {
var obj = {};
for (var i = 0, l = arr.length; i < l; i++) {
var thisDate = arr[i];
var day = pad(thisDate.getDate());
var month = pad(thisDate.getMonth() + 1);
var year = thisDate.getFullYear();
var key = [year, day, month].join('-');
obj[key] = obj[key] || 0;
obj[key]++;
}
return obj;
}
getCount(arr); // Object { 2014-04-12: 1, 2014-05-12: 3 }
DEMO
I came across the same issue and found this solution which uses Map()
`
calc = (obj) => {
const orders = []
const dates_map = new Map()
//iterate through all the objects inside the orders array
orders.forEach(order => {
// format and get the date
const date = new Date(order.created_at).toLocaleDateString('en-GB')
//check if the date key exists in the Map() and save it in a temp
const temp = dates_map.get(date) || false
// if it does not exist
if (temp) {
// clone the object
const previous = {...temp}
// increase counter
previous.count += 1
dates_map.set(date, previous)
}else{
//create new object to avoid overwriting
const result = {}
result.count = 1
dates_map.set(date, result)
}
})
console.log(dates_map)
}
And this is the output
Output: Map(3) {
'08/05/2021' => { count: 2 },
'09/05/2021' => { count: 1 },
'11/05/2021' => { count: 2,}
}
`
I have an array with the following values (example):
[
1367848800000: true,
1367935200000: true,
1368021600000: true,
1368108000000: true,
1368194400000: true,
1368367200000: true,
1368540000000: true,
1368626400000: true,
1368712800000: true
]
Where the index is a date time. The date time will always be at 12:00:00 on a date.
In this example, the first five dates are consecutive, then one day by itself, and then another group of 3 dates. An example of what I mean is below.
Now, what I am trying to do is find sequential dates and put them into an array as follows:
[
1367848800000,
1367935200000,
1368021600000,
1368108000000,
1368194400000
],
[
1368367200000,
1368540000000,
1368626400000,
],
[
1368712800000Ω
]
So in the end, I have an array, with 3 arrays of all the times.
I have tried numerous pieces of code, but everything bugs out and nothing is worth posting on here. Any help would be much appreciated!
The following approach uses array .reduce() method:
var arr = [1367848800000, 1367935200000, 1368021600000,
1368108000000, 1368194400000, 1368367200000,
1368540000000, 1368626400000, 1368712800000],
i = 0,
result = arr.reduce(function(stack, b) {
var cur = stack[i],
a = cur ? cur[cur.length-1] : 0;
if (b - a > 86400000) {
i++;
}
if (!stack[i])
stack[i] = [];
stack[i].push(b);
return stack;
}, []);
console.log(result);
DEMO: http://jsfiddle.net/gbC8B/1/
Sth like this could do:
function sequentialize(dArr) {
dArr = Object.keys(dArr).slice().sort();
var last;
var arrs = [[]];
for (var i = 0, l = dArr.length; i < l; i++) {
var cur = new Date();
cur.setTime(dArr[i]);
last = last || cur;
if (isNewSequence(cur, last)) {
arrs.push([]);
}
arrs[arrs.length - 1].push(cur.getTime()); //always push to the last index
last = cur;
}
return arrs;
function isNewSequence(a, b) {
if (a.getTime() - b.getTime() > (24 * 60 * 60 * 1000))
return true;
return false;
}
}
Now if you pass your example Array/Object to the sequentialize function
var dates = {
1367848800000: true,
1367935200000: true,
1368021600000: true,
1368108000000: true,
1368194400000: true,
1368367200000: true,
1368540000000: true,
1368626400000: true,
1368712800000: true
};
console.log(sequentialize(dates));
This gives the following output
[
[
1367848800000,
1367935200000,
1368021600000,
1368108000000,
1368194400000
],
[
1368367200000
],
[
1368540000000,
1368626400000,
1368712800000
]
]
This simply
creates an array out of the Date keys,
Sorts them
Iterates over them
If the difference of the Current and Last Date is greate than a day
Push a new Array to the Sequence Array
Push the Current Date to the last Array in the Sequence Array
Demo on JSBin
Note: You may have to change the isNewSequence function to actually fit your needs
Gotta love these puzzles. Nice answers everyone, here's mine more jQueryish approach.
var datearray = {
1367848800000: true,
1367935200000: true,
1368021600000: true,
1368108000000: true,
1368194400000: true,
1368367200000: true,
1368540000000: true,
1368626400000: true,
1368712800000: true
};
$(function() {
var result = dateSequences(datearray);
}
function dateSequences(array) {
// parse json object to array of keys
var keys = Object.keys(array);
// sort it up
keys = keys.sort();
// convert them to dates
var dates = new Array();
$.each(keys, function(i) {
dates.push(new Date(parseInt(keys[i])));
});
// now we have array of dates, search for sequential dates
var final = new Array();
var prevdate = undefined;
var currentseq = 0;
$.each(dates, function(i, d) {
// undefined?
// first sequence
if (prevdate == undefined) {
final.push(new Array());
final[currentseq].push(d);
}
else {
// compare if difference to current date in loop is greater than a day
var comp=new Date();
comp.setDate(prevdate.getDate()+2);
// Advance sequence if it is
if (comp < d) {
currentseq++;
final[currentseq] = new Array();
}
// Push the date to current sequence
final[currentseq].push(d);
}
// store previous
prevdate = d;
});
return final;
}
Fiddle:
http://jsfiddle.net/f57Ah/1/
tried array sort with forEach
var dates = [1367848800000, 1367935200000, 1368021600000,
1368108000000, 1368194400000, 1368367200000,
1368540000000, 1368626400000, 1368712800000];
var k = 0 , sorted = [[]];
dates.sort( function ( a, b ){
return +a > +b ? 1 : +a == +b ? 0: -1;
})
.forEach( function( v , i ){
var a = v,b = dates[i+1]||0;
sorted[k].push( +a );
if ( (+b - +a) > 86400000) {
sorted[++k] = []
}
});
Later you can sort them per counts
sorted.sort( function ( a,b ){
return a.length > b.length ? -1: 1;
});
The sorted array contains desired result jsfiddle
// Preconditions: singleArray contains the input array with each element corresponding to a time index. singleArray is sorted.
var outputArray = new Array();
var stack = new Array();
var stackSize = 0;
var i;
for( i = 0; i < singleArray.length; i++ )
{
// Get the last element on the stack
var lastElement = (stackSize == 0) ? 0 : stack.pop();
// Compare to see if difference is one day
if( singleArray[i] - lastElement == 86400000 ) // 24 * 60 * 60 * 1000
{
// Dates are 1 day apart
if( lastElement != 0 ) stack.push(lastElement);
stack.push(singleArray[i]);
stackSize++;
}
else
{
if( lastElement != 0 ) stack.push(lastElement);
var tempQueue = new Array();
while(stackSize > 0)
{
// Build up a new array containing consecutive days
// using a queue
tempQueue.push(stack.pop());
stackSize--;
}
// Push the consecutive days onto the next place in the output array.
outputArray.push(tempQueue);
// Start a new group of consecutive dates
stack.push(singleArray[i]);
stackSize++;
}
}