Reputation: 326
What I want?
Form groups of dates that are consecutive.
What consecutive means?
15-05-2020, 16-05-2020, 17-05-2020...
How we group them?
[
[4114696980000,4114783380000,4114869780000],
[4120485780000,4120572180000,4120658580000,4120744980000]
]
So in each array we have groups of dates that are consecutive.
What dates are not consecutive?
26-05-2020 and 28-05-2020 because after day 26, the next one is 27-05-2020, so we would obtain two arrays, one for 26-05-2020 and other for 28-05-2020.
Do I have a function to do that? Yes.
Is that function working? No.
Why? All my days are consecutive, but it gives me two arrays (groups) and I cant get why It does that.
CODE:
var arr = [4128175380000,4128261780000,4128348180000,
4128434580000,4128520980000,4128607380000,
4128697380000,4128783780000,4128870180000],
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);
The result should be just one array with all dates because they are consecutive..
Lets clarify consecutive days with this snippet converting the dates to readable form:
var arr = [4128175380000,4128261780000,4128348180000,
4128434580000,4128520980000,4128607380000,
4128697380000,4128783780000,4128870180000];
function getStringDatesFormat(arr) {
for (var i=0; i < arr.length; i++) {
console.log(new Date(arr[i]).toDateString());
}
}
getStringDatesFormat(arr);
As you can see in the results, all the days are consecutive, there is no day left between so why it breaks them into two arrays the above function code?
Edit: Output from the above
Mon Oct 25 2100 20:23:00 GMT+0100 (British Summer Time)
Tue Oct 26 2100 20:23:00 GMT+0100 (British Summer Time)
Wed Oct 27 2100 20:23:00 GMT+0100 (British Summer Time)
Thu Oct 28 2100 20:23:00 GMT+0100 (British Summer Time)
Fri Oct 29 2100 20:23:00 GMT+0100 (British Summer Time)
Sat Oct 30 2100 20:23:00 GMT+0100 (British Summer Time)
Sun Oct 31 2100 20:23:00 GMT+0000 (Greenwich Mean Time)
Mon Nov 01 2100 20:23:00 GMT+0000 (Greenwich Mean Time)
Tue Nov 02 2100 20:23:00 GMT+0000 (Greenwich Mean Time)
Upvotes: 1
Views: 1856
Reputation: 1743
Given your definition of consecutive and the dates you've provided, it is expected that your function is creating two child arrays.
4128697380000 - 4128607380000 = 90000000
Since this is greater than 86400000, these days aren't consecutive (according to your condition).
If you convert them to dates, they are indeed consecutive; but as points in time they're separated by more than 86400000 milliseconds.
To get the results you expect, you need to convert them to dates first and check if they are consecutive. For that you can use a library like date-fns or momentjs.
For example, with date-fns you could check for consecutive dates like this:
if(isAfter(b, a)) {
i++;
}
Assuming you've already mapped the values to dates using fromUnixTime
Upvotes: 1
Reputation: 4912
Your question is basically, how does one group numbers from a list by whether they are consecutive to one another?
It's ambiguous exactly what you mean by consecutive; assuming you mean consecutive on the number line as opposed to in the array, this will work. Note there is nothing special about dates. It will work for all numbers.
const numbers = [123, 124, 0, 125, 1, 2, 4, 6, 2, 9, 10, 11, 14];
const groups = numbers.reduce((groups, number, i) => {
const group = groups.find((group) => group.find((n) => Math.abs(n - number) === 1));
group ? group.push(number) : groups.push([number]);
return (i === numbers.length - 1)
? groups
.map((g) => g.sort((a, b) => a - b))
.sort(([a], [b]) => a - b)
: groups;
}, []);
console.log(groups);
Upvotes: 0