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

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

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


当前回答

这里是一个仅使用递归和slice()的非突变解决方案。

const splitToChunks = (arr, chunkSize, acc = []) => (
    arr.length > chunkSize ?
        splitToChunks(
            arr.slice(chunkSize),
            chunkSize,
            [...acc, arr.slice(0, chunkSize)]
        ) :
        [...acc, arr]
);

然后简单地像splitToChunks([1,2,3,4,5], 3)一样使用它来获得[[1,2,3],[4,5]]。

这里有一个小提琴供你尝试:https://jsfiddle.net/6wtrbx6k/2/

其他回答

这个问题可能有很多解决方案。

我最喜欢的一个是:

function chunk(array, size) { const chunked = []; for (element of array){ let last = chunked[chunked.length - 1]; if(last && last.length != size){ last.push(element) }else{ chunked.push([element]) } } return chunked; } function chunk1(array, size) { const chunked = []; let index = 0; while(index < array.length){ chunked.push(array.slice(index,index+ size)) index += size; } return chunked; } console.log('chunk without slice:',chunk([1,2,3,4,5,5],2)); console.log('chunk with use of slice funtion',chunk1([1,2,3,4,5,6],2))

我在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;
}

我的目标是在纯ES6中创建一个简单的非突变解决方案。javascript的特性使得在映射之前必须填充空数组:-(

function chunk(a, l) { 
    return new Array(Math.ceil(a.length / l)).fill(0)
        .map((_, n) => a.slice(n*l, n*l + l)); 
}

这个带有递归的版本似乎更简单,也更引人注目:

function chunk(a, l) { 
    if (a.length == 0) return []; 
    else return [a.slice(0, l)].concat(chunk(a.slice(l), l)); 
}

ES6中荒谬的弱数组函数可以制作出很好的谜题:-)

array.slice()方法可以根据需要从数组的开头、中间或结尾提取切片,而不需要改变原始数组。

const chunkSize = 10;
for (let i = 0; i < array.length; i += chunkSize) {
    const chunk = array.slice(i, i + chunkSize);
    // do whatever
}

最后一个块可能小于chunkSize。例如,当给定一个包含12个元素的数组时,第一个块将有10个元素,第二个块只有2个。

注意,chunkSize为0将导致无限循环。

编辑:@mblase75在我写我的答案时在前面的答案上添加了更简洁的代码,所以我建议使用他的解决方案。

你可以使用这样的代码:

var longArray = ["Element 1","Element 2","Element 3", /*...*/];
var smallerArrays = []; // will contain the sub-arrays of 10 elements each
var arraySize = 10;
for (var i=0;i<Math.ceil(longArray.length/arraySize);i++) {
    smallerArrays.push(longArray.slice(i*arraySize,i*arraySize+arraySize));
}

修改arraySize的值可以改变较小数组的最大长度。