让我们说我有一个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 ] ]

与许多其他解决方案相比,生成器的一个优点是不会创建多个不必要的数组。