JavaScript获取连续日期的数组

18

我有一个数组,其具有以下值(示例):

   [
      1367848800000: true,
      1367935200000: true,
      1368021600000: true,
      1368108000000: true,
      1368194400000: true,
      1368367200000: true,
      1368540000000: true,
      1368626400000: true,
      1368712800000: true
    ]

索引是一个日期时间。这个日期时间总是在某一天的12:00:00。

在这个例子中,前五个日期是连续的,然后有一个单独的一天,接着又是另一组3个日期。下面是我的意思的一个示例。

日历上的日期

现在,我正在尝试查找连续的日期并将它们放入以下数组:

   [
      1367848800000,
      1367935200000,
      1368021600000,
      1368108000000,
      1368194400000
   ],
   [
      1368367200000,
      1368540000000,
      1368626400000,
   ],
   [
      1368712800000Ω
   ]

最终,我有一个包含3个时间数组的数组。 我尝试了许多代码,但所有东西都出错了,没有值得发布的。任何帮助将不胜感激!


2
你应该发布其中一份那些无数的代码。 - Adil Shaikh
7
我们应该更多地投票支持这种格式良好、解释清晰的问题!+1 - Nick N.
你的示例将会产生四个数组,因为第二个数组中前两个日期之间的差距是两天。 - Andreas
5个回答

4
以下方法使用数组.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/


完美地工作了!我选择了你的代码,因为它看起来非常简洁明了。非常感谢你。 - MichaelH
@MichaelH 不客气!我忘了提到一点,即数组.reduce()可能不被古老的浏览器支持,而MDN建议使用兼容性shim(如果你真的需要它)。 - VisioN
幸运的是,我们只支持现代浏览器。干杯。 - MichaelH
为什么数组长度为4,最理想的情况是只创建三个嵌套数组。 - Prasanna

1
这样的东西可以做到:

  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
      ]
  ]

这个简单的程序:

  1. 将日期键创建为一个数组,

  2. 对它们进行排序,

  3. 遍历它们,

  4. 如果当前日期和上一个日期之间的差异大于一天,

  5. 将一个新的数组推送到序列数组中,

  6. 将当前日期推送到序列数组中最后一个数组中。

    演示 JSBin

注意:您可能需要更改 isNewSequence 函数以适合您的需求。


1
// 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++;
    }

}

不幸的是,JavaScript 没有 peek 方法,因此我们必须将最后一个元素推回。 - ose

1

我喜欢这些谜题。大家的答案都很好,这是我的更加jQuery风格的方法。

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/


1
尝试使用数组的sortforEach方法。
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;
});
< p > sorted 数组包含所需的结果jsfiddle


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接