让我们说我有一个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个元素?
当前回答
我试过递归函数…
const chunk = (arr, n) =>
arr.length ? [arr.slice(0, n), ...chunk(arr.slice(n), n)] : [];
……这很好,很短,但似乎是@AymKdn回答1000个元素用时的256倍,10000个元素用时的1058倍!
其他回答
我只是在groupBy函数的帮助下写了这个。
// utils const group = (source) => ({ by: (grouping) => { const groups = source.reduce((accumulator, item) => { const name = JSON.stringify(grouping(item)); accumulator[name] = accumulator[name] || []; accumulator[name].push(item); return accumulator; }, {}); return Object.keys(groups).map(key => groups[key]); } }); const chunk = (source, size) => group(source.map((item, index) => ({ item, index }))) .by(x => Math.floor(x.index / size)) .map(x => x.map(v => v.item)); // 103 items const arr = [6,2,6,6,0,7,4,9,3,1,9,6,1,2,7,8,3,3,4,6,8,7,6,9,3,6,3,5,0,9,3,7,0,4,1,9,7,5,7,4,3,4,8,9,0,5,1,0,0,8,0,5,8,3,2,5,6,9,0,0,1,5,1,7,0,6,1,6,8,4,9,8,9,1,6,5,4,9,1,6,6,1,8,3,5,5,7,0,8,3,1,7,1,1,7,6,4,9,7,0,5,1,0]; const chunks = chunk(arr, 10); console.log(JSON.stringify(chunks));
这就是我对这个话题的贡献。我想.reduce()是最好的方法。
Var segment = (arr, n) => arr.reduce((r,e,i) => i%n ?(r [r.length-1] .push (e), r) (r.push([e]), r), []), arr = Array.from({length: 31}).map((_,i) => i+1); Res = segment(arr,7); console.log (JSON.stringify (res));
但是上面的实现不是很有效,因为.reduce()运行在所有arr函数中。一个更有效的方法(非常接近最快的强制解决方案)是,迭代缩减(要分块)数组,因为我们可以通过Math.ceil(arr/n);提前计算它的大小。一旦我们有一个空的结果数组,比如array (Math.ceil(arr.length/n)).fill();剩下的是将arr数组的切片映射到它。
功能块(加勒比海盗,n) { var r = Array(Math.ceil(arr.length/n)).fill(); 返回r.map((e,i) => arr。片(我* n * n + n)); } arr = Array.from({length: 31},(_,i) => i+1); Res = chunk(arr,7); console.log (JSON.stringify (res));
到目前为止还不错,但我们仍然可以进一步简化上面的片段。
var chunk = (a,n) => Array.from({length: Math.ceil(a.length/n)}, (_,i) => a.slice(i*n, i*n+n)), arr = Array.from({length: 31},(_,i) => i+1), res = chunk(arr,7); console.log(JSON.stringify(res));
我在jsperf.com上测试了不同的答案。结果可以在https://web.archive.org/web/20150909134228/https://jsperf.com/chunk-mtds上找到
最快的函数(从IE8开始运行)是这个:
function chunk(arr, chunkSize) {
if (chunkSize <= 0) throw "Invalid chunk size";
var R = [];
for (var i=0,len=arr.length; i<len; i+=chunkSize)
R.push(arr.slice(i,i+chunkSize));
return R;
}
这是我能想到的最有效、最直接的解决方案:
function chunk(array, chunkSize) {
let chunkCount = Math.ceil(array.length / chunkSize);
let chunks = new Array(chunkCount);
for(let i = 0, j = 0, k = chunkSize; i < chunkCount; ++i) {
chunks[i] = array.slice(j, k);
j = k;
k += chunkSize;
}
return chunks;
}
我最喜欢的是生成器generateChunks和附加函数getChunks来执行生成器。
function* generateChunks(array, size) {
let start = 0;
while (start < array.length) {
yield array.slice(start, start + size);
start += size;
}
}
function getChunks(array, size) {
return [...generateChunks(array, size)];
}
console.log(getChunks([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)) // [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ], [ 9 ] ]
作为这里的补充,生成器使用进一步的getPartitions函数生成分区,以获得n个相同大小的数组。
function generatePartitions(array, count) {
return generateChunks(array, Math.ceil(array.length / count));
}
function getPartitions(array, count) {
return [...generatePartitions(array, count)];
}
console.log(getPartitions([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)) // [ [ 0, 1, 2, 3 ], [ 4, 5, 6, 7 ], [ 8, 9 ] ]
与许多其他解决方案相比,生成器的一个优点是不会创建多个不必要的数组。