3

我正在尝试使用下划线从 javascript 中的数组中获取一系列子集。这就是我想要实现的目标:

Original array: [1,1,1,2,2,2,0,0,0,1,1,1]
Expected result: [1,1,1] [2,2,2] [0,0,0] [1,1,1]

当我使用下划线的过滤方法时,我得到三个数组:[1,1,1,1,1,1] [2,2,2] [0,0,0];我希望最后一个 1 的数组不会混合。

我试过的:

_.filter(array, function(e){
     return e === 1;
})

拆分原始数组的标准是连续相等的数字必须形成一个新数组,但如果该数字出现在原始数组中的后面,则该连续相等的数字必须形成一个数组。

有没有办法使用下划线来做到这一点,还是应该用循环来完成?

谢谢

4

6 回答 6

1

不确定 underscrore.js 中是否有特定的东西可以做到这一点,但我确信它可以用下划线语法来完成。但是,您可以在 POJS 中执行类似的操作。

Javascript

var testArray = [NaN, NaN, NaN, undefined, undefined, undefined, null, null, null, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1];

function is(x, y) {
    if (x === y) {
        if (x === 0) {
            return 1 / x === 1 / y;
        }

        return true;
    }

    var x1 = x,
        y1 = y;

    return x !== x1 && y !== y1;
}

function arraySplitToGroups(array) {
    var length = array.length,
        i = 0,
        newArray = [],
        subArray = [],
        current,
        last;

    while (i < length) {
        current = array[i];

        if (!is(last, current)) {
            if (subArray.length) {
                newArray.push(subArray);
            }

            subArray = [];
        }

        subArray.push(current);
        last = current;
        i += 1;
    }

    if (subArray.length) {
        newArray.push(subArray);
    }

    return newArray;
}

console.log(arraySplitToGroups(testArray));

输出

[ [NaN, NaN, NaN], [undefined, undefined, undefined], [null, null, null], [1, 1, 1], [2, 2, 2], [0, 0, 0], [1, 1, 1] ] 

jsfiddle 上

更新:纯粹出于兴趣,我把页面上当前的所有答案都为他们创建了一个jsperf

于 2013-06-18T08:33:43.713 回答
1

我想我有一些非常简单明了的东西:

function groupValues(arr) {
    var o=[];
    var temp=0;
    for (var i=0;i<arr.length;i++){
        if (i<=0 || arr[i]!==arr[i-1]) {
            if (i>0) {
                ++temp;
            }
            o[temp]=[];
        }
        o[temp].push(arr[i]);
    }
    return o;
}

你可以看看这个工作FIDDLE

于 2013-06-18T10:02:44.633 回答
1

一个普通的旧Javascript解决方案:

小提琴

var original = [1,1,1,2,2,2,0,0,0,1,1,1];

var newArr = [], currentValue = null, currentArr;

if(original.length > 0){
    for(var i=0; i<original.length; i++){
        if(currentValue == null){
            currentValue = original[i];
            currentArr = [currentValue];
        } else {
            if(currentValue == original[i]){
                currentArr.push(currentValue);
            } else {
                newArr.push(currentArr);
                currentArr = [original[i]];
            }
        }
        currentValue = original[i];
    }
    newArr.push(currentArr);
}

输出:

[[1,1,1],[2,2,2],[0,0,0],[1,1,1]] 
于 2013-06-18T08:30:11.643 回答
0

可以为您完成工作的oneliner将是:

var input = [1,1,1,2,2,2,0,0,0,1,1,1]; 
var output = (input.join(',')+',').match(/(\d*,)\1+/g).map(function(str){return str.replace(/,$/,'').split(',').map(Number);})

基本上它的作用:

  (input.join(',') + ',') // concatenate all numbers with a ',', and add a trailing comma to help the matching
     .match(/(\d*,)\1+/g) // match groups of numbers of the same type with comma ( "1,1,2,"  > ["1,1", "2,"] ). The * is to support null/undefined values in the original array
     .map(                // replace every match (only works in modern browsers, but you can replace it with _.map )
           function() {
              return str.replace(/,$/, '')  // remove trailing ', '
                        .split(',')         // and split the string by , "1,1,1" > [1,1,1]
                        .map(Number)        // map everything back to Number (converts undefined / null values to 0 as a sideeffect, but keeps them as a group
           }
      );

如果您不想依赖map仅由现代浏览器提供的可用性,您可以像这样使用下划线映射:

var input = [1,1,1,2,2,2,0,0,0,1,1,1]; 
var output = _.map((input.join(',')+',').match(/(\d*,)\1+/g), function(str){ return _.map(str.replace(/,$/,'').split(','), Number);});

软件

正如在 Xotic750 进行的 jsperf 分析中可见的那样是性能最低的解决方案。我只是将其列为替代方法,也许是最短的方法。

于 2013-06-18T08:54:35.050 回答
0

像这样写一个简单的函数:

function splitArray(original) {
    var newArr = [], currentValue, currentArr;

    for (var i = 0; i < original.length; i++) {
       if (i === 0 || currentValue !== original[i]) {
         currentArr = [];
         newArr.push(currentArr);
       }
       currentArr.push(currentValue = original[i]);
    }

    return newArr;
}

看工作jsFiddle

它基于 MrCode 的示例,但代码较少。

于 2013-06-18T08:51:32.957 回答
0
var original = [1,1,1,1,1,2,2,2,0,0,0,1,1,1,3,3];
var result = [];
var temp = [];
_.each(original,function(num,index){
     temp.push(num);
     if(original[index+1] != 'undefined' && num != original[index+1])
    {
        result.push(temp);
        temp = [];
   }
});
console.log(result);

小提琴:http: //jsfiddle.net/2AChG/

于 2013-06-18T08:55:05.203 回答