让我们说我有一个Javascript数组看起来如下:
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?
让我们说我有一个Javascript数组看起来如下:
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?
当前回答
使用Array.prototype.reduce()的另一个解决方案:
Const chunk = (array, size) => 数组中。Reduce ((acc, _, i) => { If (i % size === 0) ac .push(数组。切片(i, i + size)) 返回acc }, []) / /使用方法: Const数= [1,2,3,4,5,6,7,8,9,10] Const chunked = chunk(number, 3) console.log(分块)
这个解决方案与Steve Holgado的解决方案非常相似。但是,因为这个解决方案没有利用数组扩展,也没有在reducer函数中创建新数组,所以它比其他解决方案更快(参见jsPerf test),而且主观上更可读(语法更简单)。
在每n次迭代(其中n = size;从第一次迭代开始),累加器数组(acc)附加了数组的一个块(array。Slice (i, i + size)),然后返回。在其他迭代中,累加器数组按原样返回。
如果size为零,该方法返回一个空数组。如果size为负,则该方法返回破碎的结果。因此,如果在您的情况下需要,您可能需要对负的或非正的大小值进行处理。
如果在你的情况下速度很重要,一个简单的for循环将比使用reduce()更快(参见jsPerf测试),一些人可能会发现这种风格更易于阅读:
function chunk(array, size) {
// This prevents infinite loops
if (size < 1) throw new Error('Size must be positive')
const result = []
for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size))
}
return result
}
其他回答
下面是一个使用reduce的ES6版本
const perChunk = 2 //每个chunk有2个项目 const inputArray = ['a','b','c','d','e'] const result = inputArray。reduce((resultArray, item, index) => { const chunkIndex = Math.floor(index/perChunk) 如果(! resultArray [chunkIndex]) { resultArray[chunkIndex] =[] //启动一个新的chunk } resultArray [chunkIndex] .push(项) 返回resultArray }, []) console.log(结果);// result: [['a','b'], ['c','d'], ['e']]]
并且您已经准备好连接进一步的映射/缩减转换。 输入数组保持不变
如果你喜欢更短但可读性较差的版本,你可以在混合中添加一些concat,以获得相同的最终结果:
inputArray.reduce((all,one,i) => {
const ch = Math.floor(i/perChunk);
all[ch] = [].concat((all[ch]||[]),one);
return all
}, [])
你可以使用余数运算符将连续的项放入不同的块中:
const ch = (i % perChunk);
如果你正在使用下划线JS,只需使用:
var result = _.chunk(arr,elements_per_chunk)
无论如何,大多数项目已经使用下划线作为依赖项。
好吧,让我们从一个相当严格的开始:
function chunk(arr, n) {
return arr.slice(0,(arr.length+n-1)/n|0).
map(function(c,i) { return arr.slice(n*i,n*i+n); });
}
它是这样使用的:
chunk([1,2,3,4,5,6,7], 2);
然后我们就有了这个紧密的减速器函数:
function chunker(p, c, i) {
(p[i/this|0] = p[i/this|0] || []).push(c);
return p;
}
它是这样使用的:
[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);
因为当我们将它绑定到一个数字时,小猫就死了,我们可以像这样手动curry:
// Fluent alternative API without prototype hacks.
function chunker(n) {
return function(p, c, i) {
(p[i/n|0] = p[i/n|0] || []).push(c);
return p;
};
}
它是这样使用的:
[1,2,3,4,5,6,7].reduce(chunker(3),[]);
然后是仍然非常紧凑的函数,它可以一次性完成所有操作:
function chunk(arr, n) {
return arr.reduce(function(p, cur, i) {
(p[i/n|0] = p[i/n|0] || []).push(cur);
return p;
},[]);
}
chunk([1,2,3,4,5,6,7], 3);
基于数组的ES6一行方法。原型缩减和推送方法:
const doChunk = (list, size) => list.reduce((r, v) =>
(!r.length || r[r.length - 1].length === size ?
r.push([v]) : r[r.length - 1].push(v)) && r
, []);
console.log(doChunk([0,1,2,3,4,5,6,7,8,9,10,11,12], 5));
// [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12]]
下面是一个使用ImmutableJS的解决方案,其中items是一个不可变列表,size是所需的分组大小。
const partition = ((items, size) => {
return items.groupBy((items, i) => Math.floor(i/size))
})