有一组数字[1, 2, 3, 4, 7, 8, 11, 15, 16, 17, 18]
,我们如何使用underscore.js将它们分组为连续数字组。
所以期望的输出是4组(1-4,7-8,11和15-18)
[[1, 2, 3, 4], [7, 8], [11], [15, 16, 17, 18]]
答案 0 :(得分:4)
我会用reduce来做,而不用担心另一个库。
[1, 2, 3, 4, 7, 8, 11, 15, 16, 17, 18].reduce((arr, val, i, a) => {
if (!i || val !== a[i - 1] + 1) arr.push([]);
arr[arr.length - 1].push(val);
return arr;
}, []);
var result = [1, 2, 3, 4, 7, 8, 11, 15, 16, 17, 18].reduce((arr, val, i, a) => {
if (!i || val !== a[i - 1] + 1) arr.push([]);
arr[arr.length - 1].push(val);
return arr;
}, []);
console.log(result);
答案 1 :(得分:0)
第一次发布问题并立即回答自己。想到其他人可能需要这样做,我想保存这个以供将来参考。
受this C#解决方案的启发,我编写了以下underscore.js mixin:
_.mixin({
groupByAdjacent: (list, iteratee) => {
let i = 0;
let length = 0;
const groupList = [];
let group = [list[0]];
let pred = list[0];
for (i = 1, length = list.length; i < length; i++) {
if (iteratee(pred, list[i])) {
group.push(list[i]);
} else {
groupList.push(group);
group = [list[i]];
}
pred = list[i];
}
groupList.push(group);
return groupList;
},
});
这样的用法:
const numbers = [1, 2, 3, 4, 7, 8, 11, 15, 16, 17, 18];
const groupsOfNumbers = _.groupByAdjacent(numbers, (x, y) => {
return ((parseInt(x, 10) + 1) == parseInt(y, 10))
});
console.log(groupsOfNumbers);
或者,如果您需要将属性中的连续数字对象分组,我们也可以对对象进行分组:
const numbersInObjects = [{ n: 1 }, { n: 2 }, { n: 3 }, { n: 4 }, { n: 7 }, { n: 8 }, { n: 11 }, { n: 15 }, { n: 16 }, { n: 17 }, { n: 18 }];
const groupsOfNumbersInObjects = _.groupByAdjacent(numbersInObjects, (x, y) => {
return ((parseInt(x.n, 10) + 1) == parseInt(y.n, 10))
});
如果有人可以缩短它,那就太棒了!我希望摆脱for循环,但我需要跳过第一项,因此_.each
无法正常工作。
答案 2 :(得分:0)
function group(arr){
result = [],
array = [],
bool = true;
arr.forEach(function(v,i){
if (v == (arr[i+1] - 1)) {
if (bool) { array.push(v); bool = false;}
array.push(arr[i+1]);
} else if ((v != arr[i-1] + 1) && (v != arr[i+1] - 1)) {
result.push([v]);
} else {
result.push(array);
array = [];
bool = true;
}
});
console.log(result);
}
group([1, 2, 3, 4, 7, 8, 11, 15, 16, 17, 18]);