我试图使用下划线从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;
})
分割原始数组的标准是连续的相等数字必须形成一个新数组,但如果数字在原始数组中稍后出现,则该连续相等数字必须形成 new 数组。
有没有办法使用下划线来完成此操作,还是应该使用循环来完成?
由于
答案 0 :(得分: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]]
答案 1 :(得分: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] ]
上
更新:就像纯粹的兴趣一样,我把当前页面上的所有答案都创建为jsperf。
答案 2 :(得分: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。
答案 3 :(得分: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的示例,但代码较少。
答案 4 :(得分: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
provided by only modern browsers的可用性,可以使用下划线地图:
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);});
<强> Bware 强>
在 Xotic750 制作的jsperf analysis中可以看到,这是性能最差的解决方案。我只是将它列为替代方案,也许是最短的方式。
答案 5 :(得分: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);