让我们说我有一个Javascript数组看起来如下:

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

什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?


当前回答

尽量避免搞乱原生原型,包括Array。原型,如果你不知道谁将使用你的代码(第三方、同事、你自己等)。

有一些方法可以安全地扩展原型(但不是在所有浏览器中),也有一些方法可以安全地使用从扩展原型创建的对象,但更好的经验法则是遵循最小意外原则,并完全避免这些做法。

如果你有时间,可以看看Andrew Dupont的JSConf 2011演讲,“Everything is allowed: Extending Built-ins”,关于这个话题的讨论。

但回到问题上来,虽然上面的解决方案是可行的,但它们过于复杂,需要不必要的计算开销。以下是我的解决方案:

function chunk (arr, len) {

  var chunks = [],
      i = 0,
      n = arr.length;

  while (i < n) {
    chunks.push(arr.slice(i, i += len));
  }

  return chunks;
}

// Optionally, you can do the following to avoid cluttering the global namespace:
Array.chunk = chunk;

其他回答

我的技巧是使用parseInt(i/chunkSize)和parseInt(i%chunkSize),然后填充数组

// filling items let array = []; for(let i = 0; i< 543; i++) array.push(i); // printing the splitted array console.log(getSplittedArray(array, 50)); // get the splitted array function getSplittedArray(array, chunkSize){ let chunkedArray = []; for(let i = 0; i<array.length; i++){ try{ chunkedArray[parseInt(i/chunkSize)][parseInt(i%chunkSize)] = array[i]; }catch(e){ chunkedArray[parseInt(i/chunkSize)] = []; chunkedArray[parseInt(i/chunkSize)][parseInt(i%chunkSize)] = array[i]; } } return chunkedArray; }

我最喜欢的是生成器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 ] ]

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

最有效的方法是将数组视为Iterable,并进行惰性分页。这样,它将只在请求时生成数据。下面的代码使用了iter-ops库中的操作符页:

import {pipe, page} from 'iter-ops';

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; // some input data

const i = pipe(arr, page(2)); //=> Iterable<number>

console.log(...i); //=> [ 1, 2 ] [ 3, 4 ] [ 5, 6 ] [ 7, 8 ] [ 9 ]

工作方式与任何Iterable或AsyncIterable相同。


附:我是图书馆的作者。

我试过递归函数…

const chunk = (arr, n) =>
    arr.length ? [arr.slice(0, n), ...chunk(arr.slice(n), n)] : [];

……这很好,很短,但似乎是@AymKdn回答1000个元素用时的256倍,10000个元素用时的1058倍!

使用来自lodash的chunk

lodash.chunk(arr,<size>).forEach(chunk=>{
  console.log(chunk);
})