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

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

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


当前回答

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

    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]

其他回答

下面是一个使用reduce的ES6版本

const perChunk = 2 //每个chunk有2个项目 const inputArray = ['a','b','c','d','e'] const result = inputArray。reduce((resultArray, item, index) => { const chunkIndex = Math.floor(index/perChunk) 如果(! resultArray [chunkIndex]) { resultArray[chunkIndex] =[] //启动一个新的chunk } resultArray [chunkIndex] .push(项) 返回resultArray }, []) console.log(结果);// result: [['a','b'], ['c','d'], ['e']]]

并且您已经准备好连接进一步的映射/缩减转换。 输入数组保持不变


如果你喜欢更短但可读性较差的版本,你可以在混合中添加一些concat,以获得相同的最终结果:

inputArray.reduce((all,one,i) => {
   const ch = Math.floor(i/perChunk); 
   all[ch] = [].concat((all[ch]||[]),one); 
   return all
}, [])

你可以使用余数运算符将连续的项放入不同的块中:

const ch = (i % perChunk); 

下面是一个使用ImmutableJS的解决方案,其中items是一个不可变列表,size是所需的分组大小。

const partition = ((items, size) => {
  return items.groupBy((items, i) => Math.floor(i/size))
})

这就是我对这个话题的贡献。我想.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));

一个很好的函数是:

function chunk(arr,times){
    if(times===null){var times = 10} //Fallback for users wanting to use the default of ten
   var tempArray = Array() //Array to be populated with chunks
    for(i=0;i<arr.length/times;i++){
     tempArray[i] = Array() //Sub-Arrays        //Repeats for each chunk         
   for(j=0;j<times;j++){
        if(!(arr[i*times+j]===undefined)){tempArray[i][j] = arr[i*times+j]//Populate Sub-  Arrays with chunks
    }
     else{
       j = times //Stop loop
       i = arr.length/times //Stop loop
  }
    }
     }
   return tempArray //Return the populated and chunked array
   }

用法如下:

chunk(array,sizeOfChunks)

我对它做了注释,这样你就能理解发生了什么。

(格式有点不对,我在移动设备上编程)

好吧,让我们从一个相当严格的开始:

function chunk(arr, n) {
    return arr.slice(0,(arr.length+n-1)/n|0).
           map(function(c,i) { return arr.slice(n*i,n*i+n); });
}

它是这样使用的:

chunk([1,2,3,4,5,6,7], 2);

然后我们就有了这个紧密的减速器函数:

function chunker(p, c, i) {
    (p[i/this|0] = p[i/this|0] || []).push(c);
    return p;
}

它是这样使用的:

[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);

因为当我们将它绑定到一个数字时,小猫就死了,我们可以像这样手动curry:

// Fluent alternative API without prototype hacks.
function chunker(n) {
   return function(p, c, i) {
       (p[i/n|0] = p[i/n|0] || []).push(c);
       return p;
   };
}

它是这样使用的:

[1,2,3,4,5,6,7].reduce(chunker(3),[]);

然后是仍然非常紧凑的函数,它可以一次性完成所有操作:

function chunk(arr, n) {
    return arr.reduce(function(p, cur, i) {
        (p[i/n|0] = p[i/n|0] || []).push(cur);
        return p;
    },[]);
}

chunk([1,2,3,4,5,6,7], 3);