Javascript Получает последовательные даты в массиве - программирование
Подтвердить что ты не робот

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 массивами всех времен. Я пробовал множество фрагментов кода, но все ошибки и ничего не стоит публиковать здесь. Любая помощь будет высоко оценена!

4b9b3361

Ответ 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