将数组分成块

1005

假设我有一个JavaScript数组,如下所示:

["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.

如何将一个数组分成多个小数组,每个小数组最多包含10个元素?


参见 如何将长数组拆分为较小的数组使用underscore.js拆分javascript数组 (以及链接问题中的许多重复项 linked questions)。 - Bergi
可能是将JS数组分成N个数组的重复问题。 - T J
70
对于lodash用户,您需要查找_.chunk - Ulysse BN
如果你需要最后一个块的最小大小,这里有几个选项:https://stackoverflow.com/questions/57908133/splitting-an-array-up-into-chunks-of-a-given-size-with-a-minimum-chunk-size - Ahmet Cetin
我创建了一个解决方案,合并了最佳答案:https://dev59.com/4Goy5IYBdhLWcg3wg-Ym#71483760 - Fernando Leal
@webatrisans 这回答了你的问题。如果你使用正确的标签,那么我们更容易给出正确的指针指向正确的重复内容。 - RiggsFolly
84个回答

7

这是一个递归解决方案,可以进行尾调用优化。

const splitEvery = (n, xs, y=[]) =>
  xs.length===0 ? y : splitEvery(n, xs.slice(n), y.concat([xs.slice(0, n)])) 

console.log(splitEvery(2, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))


7
in coffeescript:

b = (a.splice(0, len) while a.length)

demo 
a = [1, 2, 3, 4, 5, 6, 7]

b = (a.splice(0, 2) while a.length)
[ [ 1, 2 ],
  [ 3, 4 ],
  [ 5, 6 ],
  [ 7 ] ]

a.splice(0, 2)会从数组a中删除a[0..1]的子数组,并返回子数组a[0..1]。我正在创建一个包含所有这些数组的数组。 - Arpit Jain
2
我建议使用非破坏性的slice()方法,而不是splice()。 - Ash Blue

6

如果您正在使用Underscore JS,请使用:

var result = _.chunk(arr,elements_per_chunk)

大多数项目无论如何都已经使用underscore作为依赖。


当我看到你的答案时,我正要发布相同的回答。 - Black Mamba

6

ES6扩展函数式编程 #ohmy #ftw

const chunk =
  (size, xs) => 
    xs.reduce(
      (segments, _, index) =>
        index % size === 0 
          ? [...segments, xs.slice(index, index + size)] 
          : segments, 
      []
    );

console.log( chunk(3, [1, 2, 3, 4, 5, 6, 7, 8]) );


6

对于一个功能性的解决方案,使用Ramda

其中popularProducts是您的输入数组,5是块大小。

import splitEvery from 'ramda/src/splitEvery'

splitEvery(5, popularProducts).map((chunk, i) => {
// do something with chunk

})


6

ES6 生成器版本

function* chunkArray(array,size=1){
    var clone = array.slice(0);
    while (clone.length>0) 
      yield clone.splice(0,size); 
};
var a = new Array(100).fill().map((x,index)=>index);
for(const c of chunkArray(a,10)) 
    console.log(c);

请使用 const - Константин Ван

6

当源数组发生变化时:

let a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], aa = [], x
while((x = a.splice(0, 2)).length) aa.push(x)

// aa == [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ], [ 9 ] ]
// a == []

不改变原始数组的情况下:

let a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], aa = []
for(let i = 0; i < a.length; i += 2) aa.push(a.slice(i, i + 2))

// aa == [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ], [ 9 ] ]
// a == [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

4
这是我使用的东西,可能不是超级快,但它很简洁易懂:

let chunksplit = (stream, size) => stream.reduce((chunks, item, idx, arr) => (idx % size == 0) ? [...chunks, arr.slice(idx, idx + size)] : chunks, []);
//if the index is a multiple of the chunksize, add new array

let testArray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22];

document.write(JSON.stringify( chunksplit(testArray, 5) ));
//using JSON.stringify for the nested arrays to be shown


4
一个使用空值合并赋值的 ES2020 一行代码。

const arr = '1234567890'.split('');
const chunkSize = 3;
const r = arr.reduce((arr, item, idx) => (arr[idx / chunkSize | 0] ??= []).push(item) && arr, []);

console.log(JSON.stringify(r));


4

基于Array.prototype reducepush 方法的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]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接