基于序列拆分数组的JavaScript方法

4

I have an array like

var arr = [12, 13, 14, 17, 18, 19, 20]

我想知道如何遍历数组,以便根据序列将该数组拆分为2个数组?即,如果i + 1!= true,则创建一个新数组。

var arr = [12, 13, 14]
var arr2 = [17,18,19,20]

我正在使用lodash,并尝试使用一些使用splicefor语句,但我有点困惑?感谢任何帮助。


1
请提供更多信息,您想如何拆分?拆分三个元素后很容易,这就是您需要的全部吗? - luk2302
两个数组长度相等吗? - iraycd
我需要split函数能够识别序列何时停止?例如,12、13、14 - 然后有一个间断,直到17、18、19序列才重新开始。也就是说,当i+1 != true时,将其分割到新的数组中。 - Andy
4个回答

3

jsFiddle 上的示例

var a = [1, 2, 3, 5, 6, 7];

var r = [];
var t = [];

for (var i = 0; i < a.length; ++i)
{
    if (i == 0)
    {
        t.push(a[i]); // add the first element and continue
        continue;
    }
    if (a[i - 1] != (a[i] - 1))
    {
        // if the current is not sequential
        // add the current temporary array to arrays result
        r.push(t);

        // clear the temporary array and start over
        t = [];
    }

    t.push(a[i]);
}
r.push(t);

r将包含所有的数组。

压缩版本

function seq(e,t,n,r){t=[];n=[];for(r=0;r<e.length;++r){if(!r){n.push(e[r]);continue}if(e[r-1]!=e[r]-1){t.push(n);n=[]}n.push(e[r])}t.push(n);return t}

var result = seq([1, 2, 3, 5, 6, 7]);

2

这里是另一种更加紧凑的方法,使用underscore库中相当方便的groupByvalues方法:

var origin = [12,13,14,15,17,18,19,21,22,23];
var c = 0, result = _.values( _.groupBy(origin, function(el, i, arr) { 
  return i ? c+= (1 !== el - arr[i-1]) : 0; }) );

因此,result归档将包含所有序列作为元素。这是JSFiddle,可以进行操作。
解释: groupBy使用回调函数对源数组进行分组(每当当前处理的元素(el)与上一个元素(arr[i-1])之间的差异大于1时返回新的序列号)。它返回一个对象,因此我必须通过_.values;您可能需要或不需要此步骤。
我想知道是否可能请求类似于groupByInArray函数?实现起来应该很简单,但在这种情况下可能非常有用。

太好了!非常感谢。是的,我认为像 groupBy 这样的东西会很棒。我甚至有一个场景,就像 [[12, 0], [13, 0], [14, 0], [18,0], [19,1], [20,0]],我需要将其拆分成两个数组?所以它就像 [[12, 0], [13, 0], [14, 0]][[18,0], [19,1], [20,0]] - Andy
如果我理解正确,您可以通过轻微更改重复使用此函数:将检查 el-arr[i-1] 替换为 el[0]-arr[i-1][0]演示 - raina77ow
太棒了!非常感谢。我只是在想,如果你有一个groupByInArray函数,它也支持这些场景,那就太不可思议了,会成为Underscore库的一个重要补充。 - Andy
我是指向Underscore库本身发起拉取请求。 - raina77ow
啊,我甚至不知道有这样的东西存在,听起来和看起来就像 Haskell(至少有点像),太喜欢了 :) - luk2302

0

你是指像这样 this 吗?

function split(arr) {
    var res = [];
    var subres = [];
    for (var i = 0; i < arr.length; i++) {
        var length = subres.length;
        if (length === 0 || subres[length - 1] === arr[i] - 1) {
            subres.push(arr[i]);
        } else {
            res.push(subres);
            subres = [arr[i]];
        }
    }
    res.push(subres);
    return res;
}

是的!非常感谢。如果你熟悉lodash或underscore,是否可以更快地完成? - Andy
1
@Andy 使用任何库都不会使任何东西更快。 - Pointy

0

试试这个 :)

var array = [12,13,14,4567,789,0]; //e.g.
var index;
var previous = array[0];
for (var index = 1; index++; index < array.length) {
  if (previous + 1 == array[index]) {
    previous = array[index]; //++
  } else {
    break;
  }
}
var firstPart = array.slice(0, index + 1);
var secondPart = array.slice(index + 1);

http://jsfiddle.net/zajnH/


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