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

其他回答

下面是我使用Coffeescript列表理解的方法。可以在这里找到一篇详细介绍Coffeescript中的理解的好文章。

chunk: (arr, size) ->
    chunks = (arr.slice(index, index+size) for item, index in arr by size)
    return chunks

这里有一个更具体的案例,有人可能会觉得有价值。我还没看到这里提到过。

如果你不想要固定/均匀的数据块大小,而是想要指定拆分数组的下标怎么办?在这种情况下,你可以使用这个:

const splitArray = (array = [], splits = []) => {
  array = [...array]; // make shallow copy to avoid mutating original
  const chunks = []; // collect chunks
  for (const split of splits.reverse()) chunks.push(array.splice(split)); // go backwards through split indices and lop off end of array
  chunks.push(array); // add last remaining chunk (at beginning of array)
  return chunks.reverse(); // restore chunk order
};

然后:

splitArray([1, 2, 3, 4, 5, 6, 7, 8, 9], [4, 6]) 
// [ [1, 2, 3, 4] , [5, 6] , [7, 8, 9] ]

请注意,如果你给它非升序/重复/负/非整数/等分割索引,这将会发生有趣的事情。您可以为这些边缘情况添加检查(例如array .from(new Set(array))来消除重复。

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 ] ]

基于数组的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]]

我更喜欢使用拼接法而不是切片法。 这个解决方案使用数组长度和块大小来创建循环计数,然后循环遍历数组,在每个步骤中由于拼接而在每个操作后变得更小。

    function chunk(array, size) {
      let resultArray = [];
      let chunkSize = array.length/size;
      for(i=0; i<chunkSize; i++) {
        resultArray.push(array.splice(0, size));
      }
    return console.log(resultArray);
    }
    chunk([1,2,3,4,5,6,7,8], 2);

如果不想改变原始数组,可以使用展开操作符克隆原始数组,然后使用该数组来解决问题。

    let clonedArray = [...OriginalArray]