Javascript Получает последовательные даты в массиве
У меня есть массив со следующими значениями (пример):
[
1367848800000: true,
1367935200000: true,
1368021600000: true,
1368108000000: true,
1368194400000: true,
1368367200000: true,
1368540000000: true,
1368626400000: true,
1368712800000: true
]
Где индекс - это время даты. Дата будет всегда в 12:00:00 по дате.
В этом примере первые пять дат являются последовательными, затем один день отдельно, а затем другой группой из трех дат. Пример того, что я имею в виду, ниже.
![Dates on Calendar]()
Теперь, что я пытаюсь сделать, это найти последовательные даты и поместить их в массив следующим образом:
[
1367848800000,
1367935200000,
1368021600000,
1368108000000,
1368194400000
],
[
1368367200000,
1368540000000,
1368626400000,
],
[
1368712800000Ω
]
Итак, в конце концов, у меня есть массив с 3 массивами всех времен.
Я пробовал множество фрагментов кода, но все ошибки и ничего не стоит публиковать здесь. Любая помощь будет высоко оценена!
Ответы
Ответ 1
В следующем подходе используется метод массива .reduce()
:
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/
Ответ 2
Sth, как это могло бы сделать:
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;
}
}
Теперь, если вы передадите свой пример Array/Object
в функцию sequentialize
var dates = {
1367848800000: true,
1367935200000: true,
1368021600000: true,
1368108000000: true,
1368194400000: true,
1368367200000: true,
1368540000000: true,
1368626400000: true,
1368712800000: true
};
console.log(sequentialize(dates));
Это дает следующий вывод
[
[
1367848800000,
1367935200000,
1368021600000,
1368108000000,
1368194400000
],
[
1368367200000
],
[
1368540000000,
1368626400000,
1368712800000
]
]
Это просто
-
создает массив из ключей даты,
-
Сортирует их
-
Итерации по ним
-
Если разница Текущей и Последней Даты больше, чем день
-
Нажмите новый массив в массив последовательностей
-
Нажмите текущую дату на последний массив в массиве последовательностей
Демо на JSBin
Примечание. Возможно, вам придется изменить функцию isNewSequence
, чтобы она соответствовала вашим потребностям.
Ответ 3
// 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++;
}
}
Ответ 4
Надо любить эти головоломки. Nice отвечает всем, здесь мой более jQueryish подход.
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;
}
Скрипка:
http://jsfiddle.net/f57Ah/1/
Ответ 5
массив sort
с 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] = []
}
});
Позже вы можете сортировать их по подсчетам
sorted.sort( function ( a,b ){
return a.length > b.length ? -1: 1;
});
Массив sorted
содержит желаемый результат jsfiddle