【问题标题】:Split array into chunks将数组拆分为块
【发布时间】:2022-01-06 03:00:47
【问题描述】:

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

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

什么方法适合将数组分块(拆分)成许多较小的数组,比如说最多 10 个元素?

【问题讨论】:

标签: javascript arrays split


【解决方案1】:

这是一个使用 reduce 的 ES6 版本

var perChunk = 2 // items per chunk    

var inputArray = ['a','b','c','d','e']

var result = inputArray.reduce((resultArray, item, index) => { 
  const chunkIndex = Math.floor(index/perChunk)

  if(!resultArray[chunkIndex]) {
    resultArray[chunkIndex] = [] // start a new chunk
  }

  resultArray[chunkIndex].push(item)

  return resultArray
}, [])

console.log(result); // result: [['a','b'], ['c','d'], ['e']]

您已准备好链接进一步的 map/reduce 转换。 您的输入数组保持不变


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

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

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

const ch = (i % perChunk); 

【讨论】:

  • 这似乎是最简洁的解决方案。 chunkIndex = Math.floor(index/perChunk) 得到什么?是平均水平吗?
  • 5/2 = 2.5 和 Math.floor(2.5) = 2 所以索引为 5 的项目将放在存储桶 2 中
  • 感谢 Andrei R. 啊,所以它逐步通过 0 - 2。那么这在数学术语中叫什么?我想我的观点是我从来没有想过将每个索引除以 index / 2 来获得每个切片的索引。所以我试图围绕它转转,因为我真的很喜欢它,但在数学方面并不完全理解它。我通常这样做是为了得到一个总数的平均值,但这看起来不同。
  • 我喜欢你在这里使用 all 和 one - 比我见过和使用的其他例子更容易读懂 reduce。
  • 来自喜欢函数式编程的人的热门观点,for 循环比简化为新数组更具可读性
【解决方案2】:

js

function splitToBulks(arr, bulkSize = 20) {
    const bulks = [];
    for (let i = 0; i < Math.ceil(arr.length / bulkSize); i++) {
        bulks.push(arr.slice(i * bulkSize, (i + 1) * bulkSize));
    }
    return bulks;
}

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

打字稿

function splitToBulks<T>(arr: T[], bulkSize: number = 20): T[][] {
    const bulks: T[][] = [];
    for (let i = 0; i < Math.ceil(arr.length / bulkSize); i++) {
        bulks.push(arr.slice(i * bulkSize, (i + 1) * bulkSize));
    }
    return bulks;
}

【讨论】:

    【解决方案3】:

    示例 未更改的源数组
    并且不一次制作所有的块。 (节省内存!)

    const array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21];
    
    const chunkSize = 4
    for (var i = 0; i < array.length; i += chunkSize) {
        const chunk = array.slice(i, i + chunkSize);
        console.log('chunk=',chunk)
        // do whatever
    }
    console.log('src array didnt changed. array=',array)
    

    【讨论】:

      【解决方案4】:

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

      var i,j, temporary, chunk = 10;
      for (i = 0,j = array.length; i < j; i += chunk) {
          temporary = array.slice(i, i + chunk);
          // do whatever
      }
      

      【讨论】:

      • 请记住,如果这是一个 util 函数来断言 chunk 是 0。 (无限循环)
      • 不,最后一个块应该比其他块小。
      • @Blazemonger,确实如此!下次我会在下结论之前亲自尝试一下。我假设(错误地)将超出数组边界的输入传递给 array.slice 将是一个问题,但它工作得非常完美!
      • 对于单线(链爱好者):const array_chunks = (array, chunk_size) =&gt; Array(Math.ceil(array.length / chunk_size)).fill().map((_, index) =&gt; index * chunk_size).map(begin =&gt; array.slice(begin, begin + chunk_size));.
      • 为什么需要j?首先我认为这是一个优化,但它实际上比 for(i=0;i
      【解决方案5】:
      const array = ['a', 'b', 'c', 'd', 'e'];
      const size = 2;
      const chunks = [];
      while(array.length) {
        chunks.push(array.splice(0,size));
      }
      console.log(chunks);
      

      【讨论】:

        【解决方案6】:

        这将是我对这个主题的贡献。我想.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 数组的切片映射到其中。

        function chunk(arr,n){
          var r = Array(Math.ceil(arr.length/n)).fill();
          return r.map((e,i) => arr.slice(i*n, i*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));

        【讨论】:

          【解决方案7】:

          TypeScript 版本。演示的是 101 个随机 uid 分成 10 个组

          const idArrayLengthLimit = 10;
          const randomOneHundredOneIdArray = Array
              .from(Array(101).keys())
              .map(() => generateUid(5));
          
          function generateUid(length: number) {
            const uidString: string[] = [];
            const uidChars = 'abcdefghijklmnopqrstuvwxyz0123456789';
            for (let i = 0; i < length; i++) {
              uidString
                .push(uidChars.charAt(Math.floor(Math.random() * uidChars.length)));
            }
            return uidString.join('');
          }
          
          for (let i = 0; i < randomOneHundredOneIdArray.length; i++) {
           if(i % idArrayLengthLimit === 0){
               const result = randomOneHundredOneIdArray
                 .filter((_,id) => id >= i && id < i + idArrayLengthLimit);
              // Observe result
              console.log(result);
           }
          }
          

          【讨论】:

            【解决方案8】:

            晚了,这是我的两分钱。就像很多人说的,我首先会想到类似的东西

            chunker = (a,n) => [...Array(Math.ceil(a.length/n))].map((v,i) => a.slice(i*n, (i+1)*n))
            

            但我更喜欢这里没有看到的是这个:

            chunker = (n) => (r,v,i) => (c = Math.floor(i/n), (r[c] = r[c] || []).push(v), r)
            
            console.log(arr.reduce(chunker(3), []))
            

            有更长的变体

            chunker = (a, n) => a.reduce((r,v,i) => {
              c = Math.floor(i/n); // which chunk it belongs to
              (r[c] = r[c] || []).push(v)
              return r
            }, [])
            
            console.log(chunker(arr, 3))
            

            说明

            1. 常见的答案会首先确定块的数量,然后根据块所在的位置和每个块的大小来获取原始数组的切片

            2. chunker reducer 函数将遍历每个元素并将其放入相应评估的块的数组中。

            性能几乎相同,就我所见,reduce 方法平均慢了 4%。

            PS:reduce(ing) 的优点是可以轻松更改分组标准。在问题和示例中,标准是相邻单元格(并且映射使用切片)。但是您可能希望在“循环”中执行此操作,例如,使用 mod(% 运算符)或任何其他数学公式

            重读它让我发现公式也可以是一个参数,导致更通用的解决方案,需要 2 个函数来实现答案:

            splitter = (a, f) => a.reduce((r,v,i) => { // math formula and/or function
              c = f(v, i) || 0; // custom formula, receiving each value and index
              (r[c] = r[c] || []).push(v)
              return r
            }, [])
            
            chunker = (a, n) => splitter(a, (v,i) => Math.floor(i/n))
            
            console.log(chunker(arr, 3))
            console.log(splitter(arr, (v,i) => v % 2))  // is it even or odd?
            

            稍加改动splitter 也可用于制作命名数组(也称为对象),函数返回字符串而不是数字 :)

            【讨论】:

              【解决方案9】:

              您可以使用 Array.prototype.reduce 函数在一行中完成此操作。

              let arr = [1,2,3,4];
              function chunk(arr, size)
              {
                  let result = arr.reduce((rows, key, index) => (index % size == 0 ? rows.push([key]) : rows[rows.length-1].push(key)) && rows, []);
                  return result;
              }
                      
              console.log(chunk(arr,2));

              【讨论】:

                【解决方案10】:

                这是一个示例,我将数组拆分为 2 个元素的块,只需从数组中拼接块直到原始数组为空。

                    const array = [86,133,87,133,88,133,89,133,90,133];
                    const new_array = [];
                
                    const chunksize = 2;
                    while (array.length) {
                        const chunk = array.splice(0,chunksize);
                        new_array.push(chunk);
                    }
                
                    console.log(new_array)

                【讨论】:

                • 虽然这可能会回答问题,但稍微解释一下会非常有帮助,请单击edit 并输入一些解释。
                【解决方案11】:

                ECMA 6 中的单行

                const [list,chunkSize] = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], 6]
                
                [...Array(Math.ceil(list.length / chunkSize))].map(_ => list.splice(0,chunkSize))
                

                【讨论】:

                • 它修改了原来的list数组
                • 使用 .slice() 轻松修复.. .map((_,i) =&gt; list.slice(i*chuckSize,i*chuckSize+chuckSize))
                • 在 JSPerf 上,这比许多其他答案的性能要高得多。
                • 最好使用[ ]而不是new Array():[...Array(Math.ceil(list.length / chuckSize)].map(_ =&gt; list.splice(0,chuckSize))
                • 如果你在前面拼接,你也可以映射同一个数组本身:var split=(fields,record=2)=&gt;\n fields.map((field,index,fields)=&gt;\n fields.splice(index,record,fields.slice(index,record)));
                【解决方案12】:

                如果您不知道谁将使用您的代码(第三方、同事、您以后等),请尽量避免使用原生原型,包括 Array.prototype。

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

                如果您有时间,请观看 Andrew Dupont 在 2011 年的 JSConf 演讲,"Everything is Permitted: 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;
                

                【讨论】:

                • “避免使用原生原型”新的 js 开发者应该得到一个临时的,如果不是永久的,这句话的纹身。
                • 我多年来一直在使用 javascript,几乎没有时间花在原型上,在大多数调用函数上,从不像你看到的某些人那样进行修改。
                • 我眼中最好的建议,最简单的理解和实施,非常感谢!
                • @JacobDalton 我认为这都是大学的错。人们认为 OOP 必须无处不在。所以他们害怕“只是创建一个功能”。他们希望确保将其放入某物内。即使它根本不合适。如果没有点符号,就没有“架构”。
                • @Gherman 我也经常看到这种情况。我主要在 Laravel 工作,我店里的人倾向于创建各种经理类以“坚持”OOP,但这样做打破了 Laravel 的惯例,使项目变得更加复杂。
                【解决方案13】:

                派对迟到了,但我使用.join("") 将数组转换为一个巨大的字符串,然后使用正则表达式将.match(/.{1,7}/) 转换为最大长度为 7 的子字符串数组,从而解决了类似的问题。

                const arr = ['abc', 'def', 'gh', 'ijkl', 'm', 'nopq', 'rs', 'tuvwx', 'yz'];
                const arrayOfSevens = arr.join("").match(/.{1,7}/g);
                // ["abcdefg", "hijklmn", "opqrstu", "vwxyz"]
                

                看看它在与其他方法的速度测试中的表现会很有趣

                【讨论】:

                • 这根本不符合最初的目的。
                • 恐怕它的表现会很差,因为首先是正则表达式,然后是连接,我会说。
                【解决方案14】:

                你可以拿这个 ES6 chunk 函数,好用:

                const chunk = (array, size) =>
                  Array.from({length: Math.ceil(array.length / size)}, (value, index) => array.slice(index * size, index * size + size));
                
                const itemsPerChunk = 3;
                const inputArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
                
                const newArray = chunk(inputArray, itemsPerChunk);
                console.log(newArray.length); // 3,
                
                document.write(JSON.stringify(newArray)); //  [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ], [ 'g' ] ]

                【讨论】:

                • 喜欢这个单行代码主要是因为它不会创建任何中间辅助数组,而是创建一些相当小的对象。
                【解决方案15】:

                单线

                const chunk = (a,n)=>[...Array(Math.ceil(a.length/n))].map((_,i)=>a.slice(n*i,n+n*i));
                

                对于打字稿

                const chunk = <T>(arr: T[], size: number): T[][] =>
                  [...Array(Math.ceil(arr.length / size))].map((_, i) =>
                    arr.slice(size * i, size + size * i)
                  );
                

                演示

                const chunk = (a,n)=>[...Array(Math.ceil(a.length/n))].map((_,i)=>a.slice(n*i,n+n*i));
                document.write(JSON.stringify(chunk([1, 2, 3, 4], 2)));

                按组数分块

                const part=(a,n)=>[...Array(n)].map((_,i)=>a.slice(i*Math.ceil(a.length/n),(i+1)*Math.ceil(a.length/n)));
                

                对于打字稿

                const part = <T>(a: T[], n: number): T[][] => {
                  const b = Math.ceil(a.length / n);
                  return [...Array(n)].map((_, i) => a.slice(i * b, (i + 1) * b));
                };
                

                演示

                const part = (a, n) => {
                    const b = Math.ceil(a.length / n);
                    return [...Array(n)].map((_, i) => a.slice(i * b, (i + 1) * b));
                };
                
                document.write(JSON.stringify(part([1, 2, 3, 4, 5, 6], 2))+'<br/>');
                document.write(JSON.stringify(part([1, 2, 3, 4, 5, 6, 7], 2)));

                【讨论】:

                • 谢谢! oneliner 是最好的答案!
                • chunk([1,2,3,4],2) 产生[ [ 1, 2 ], [ 3, 4 ], [] ]。我觉得不合适。
                • 无法重现您的结果@HansBouwmeeste。 u.davwheat.dev/3Om2Au5D.png
                • 它是,但现在已修复,我应该提一下我的错
                • @大卫惠特利。确认的。我尝试了最新版本,现在效果很好。
                【解决方案16】:

                使用Array.prototype.reduce()的另一种解决方案:

                const chunk = (array, size) =>
                  array.reduce((acc, _, i) => {
                    if (i % size === 0) acc.push(array.slice(i, i + size))
                    return acc
                  }, [])
                
                // Usage:
                const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
                const chunked = chunk(numbers, 3)
                console.log(chunked)

                此解决方案与solution by Steve Holgado 非常相似。然而,由于这个解决方案没有利用数组扩展,也没有在 reducer 函数中创建新数组,因此它比其他解决方案更快(参见 jsPerf test)并且主观上更具可读性(更简单的语法)。

                在每 nth 次迭代(其中 n = size;从第一次迭代开始),累加器数组 (acc) 会附加一大块数组 (array.slice(i, i + size)) 然后返回。在其他迭代中,累加器数组按原样返回。

                如果size 为零,则该方法返回一个空数组。如果size 为负,则该方法返回损坏的结果。因此,如果您的情况需要,您可能需要对负或非正 size 值做一些事情。


                如果在您的情况下速度很重要,一个简单的for 循环会比使用reduce() 更快(请参阅jsPerf test),并且有些人可能会发现这种样式也更具可读性:

                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
                }
                

                【讨论】:

                • 你的 reduce 示例是迄今为止最干净的方法
                【解决方案17】:

                我是这样解决的:

                const chunks = [];
                const chunkSize = 10;
                for (let i = 0; i < arrayToSplit.length; i += chunkSize) {
                  const tempArray = arrayToSplit.slice(i, i + chunkSize);
                  chunks.push(tempArray);
                }
                

                【讨论】:

                  【解决方案18】:

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

                  【讨论】:

                  • 感谢@AymKdn 制定此基准:这非常有帮助!我正在使用splice approach,它以 884432 的块大小使我的 Chrome v70 浏览器崩溃。使用您建议的“切片”方法,我的代码不会再使浏览器的“渲染”过程崩溃。 :)
                  • 这是一个打字稿版本:function chunk&lt;T&gt;(array: T[], chunkSize: number): T[][] { const R = []; for (let i = 0, len = array.length; i &lt; len; i += chunkSize) R.push(array.slice(i, i + chunkSize)); return R; }
                  • chunkSize = 0 需要多长时间?一些有效的函数输入不应停止进程。
                  • @ceving 我刚刚添加了一个条件,当 chunkSize 为
                  • @AymKdn 我不确定,如果返回未修改的数组是最好的错误处理。函数的预期返回类型是Array&lt;Array&gt;。并且非正的块大小没有任何意义。所以抛出一个错误对我来说似乎是合理的。
                  【解决方案19】:

                  如果这对任何人都有用,这可以在 RxJS 6 中非常简单地完成:

                  const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
                  from(arr).pipe(bufferCount(3)).subscribe(chunk => console.log(chunk));
                  

                  输出:[1, 2, 3] [4, 5, 6] [7, 8, 9] [10, 11, 12] [13, 14, 15] [16]

                  【讨论】:

                    【解决方案20】:

                    使用生成器

                    function* chunks(arr, n) {
                      for (let i = 0; i < arr.length; i += n) {
                        yield arr.slice(i, i + n);
                      }
                    }
                    
                    let someArray = [0,1,2,3,4,5,6,7,8,9]
                    console.log([...chunks(someArray, 2)]) // [[0,1],[2,3],[4,5],[6,7],[8,9]]

                    【讨论】:

                    • 我对这个问题的所有答案感到惊讶,这些答案几乎都在使用生成器或以更复杂的方式使用它们。此解决方案的简洁性和性能非常好。
                    • 这是迄今为止最好的答案。
                    【解决方案21】:

                    我建议使用 lodash。分块是那里许多有用的功能之一。 说明:

                    npm i --save lodash
                    

                    包含在您的项目中:

                    import * as _ from 'lodash';
                    

                    用法:

                    const arrayOfElements = ["Element 1","Element 2","Element 3", "Element 4", "Element 5","Element 6","Element 7","Element 8","Element 9","Element 10","Element 11","Element 12"]
                    const chunkedElements = _.chunk(arrayOfElements, 10)
                    

                    您可以在这里找到我的示例: https://playcode.io/659171/

                    【讨论】:

                      【解决方案22】:

                      纯javascript中的一行:

                      function chunks(array, size) {
                        return Array.apply(0,{length: Math.ceil(array.length / size)}).map((_, index) => array.slice(index*size, (index+1)*size))
                      }
                      
                      // The following will group letters of the alphabet by 4
                      console.log(chunks([...Array(26)].map((x,i)=>String.fromCharCode(i + 97)), 4))

                      【讨论】:

                        【解决方案23】:

                        使用Array.prototype.splice() 拼接,直到数组有元素。

                        Array.prototype.chunk = function(size) {
                            let result = [];
                            
                            while(this.length) {
                                result.push(this.splice(0, size));
                            }
                                
                            return result;
                        }
                        
                        const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
                        console.log(arr.chunk(2));

                        更新

                        Array.prototype.splice() 填充原始数组,执行chunk() 后,原始数组 (arr) 变为 []。

                        因此,如果您想保持原始数组不变,请将arr 数据复制并保留到另一个数组中并执行相同的操作。

                        Array.prototype.chunk = function(size) {
                          let data = [...this];  
                          let result = [];
                            
                            while(data.length) {
                                result.push(data.splice(0, size));
                            }
                        
                            return result;
                        }
                        
                        const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
                        console.log('chunked:', arr.chunk(2));
                        console.log('original', arr);

                        P.S:感谢@mts-knn 提及此事。

                        【讨论】:

                        • 注意拼接会修改原始数组。如果在代码 sn-p 的末尾添加console.log(arr);,它将记录[],即arr 将是一个空数组。
                        【解决方案24】:

                        如果您使用的是 Underscore JS,只需使用:

                        var result = _.chunk(arr,elements_per_chunk)
                        

                        无论如何,大多数项目已经使用下划线作为依赖项。

                        【讨论】:

                        • 当我看到你的时,我正要发布相同的答案
                        【解决方案25】:

                        Neat and clean easy to understand

                         let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];
                         let len = nums.length ;
                        
                            const chunkArr = (arr, chunkNo) => {
                              let newArr = [];
                              for(let i = 0; i < len; i++){
                                if(nums[0] !== "" && nums[0] !== undefined ){
                                  let a = nums.splice(0,chunkNo) ; 
                                  newArr.push(a);
                                }
                              }
                               return newArr ;
                            }
                            console.log(chunkArr(nums, 5));
                        

                        【讨论】:

                          【解决方案26】:

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

                          我最喜欢的一个是:

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

                          【讨论】:

                            【解决方案27】:

                            为此 https://www.npmjs.com/package/array.chunk 创建了一个 npm 包

                            var result = [];
                            
                            for (var i = 0; i < arr.length; i += size) {
                              result.push(arr.slice(i, size + i));
                            }
                            return result;
                            

                            当使用TypedArray时

                            var result = [];
                            
                            for (var i = 0; i < arr.length; i += size) {
                              result.push(arr.subarray(i, size + i));
                            }
                            return result;
                            

                            【讨论】:

                            【解决方案28】:

                            有很多答案,但这是我使用的:

                            const chunk = (arr, size) =>
                              arr
                                .reduce((acc, _, i) =>
                                  (i % size)
                                    ? acc
                                    : [...acc, arr.slice(i, i + size)]
                                , [])
                            
                            // USAGE
                            const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
                            chunk(numbers, 3)
                            
                            // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
                            

                            首先,在将索引除以块大小时检查余数。

                            如果有余数,则返回累加器数组。

                            如果没有余数,则索引可被块大小整除,因此从原始数组中取出一个切片(从当前索引开始)并将其添加到累加器数组中。

                            因此,reduce 的每次迭代返回的累加器数组如下所示:

                            // 0: [[1, 2, 3]]
                            // 1: [[1, 2, 3]]
                            // 2: [[1, 2, 3]]
                            // 3: [[1, 2, 3], [4, 5, 6]]
                            // 4: [[1, 2, 3], [4, 5, 6]]
                            // 5: [[1, 2, 3], [4, 5, 6]]
                            // 6: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
                            // 7: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
                            // 8: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
                            // 9: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
                            

                            【讨论】:

                            • 很好的解决方案和很好的迭代视觉表示。我最终得到了一个非常相似的解决方案,我将其作为答案发布:stackoverflow.com/a/60779547
                            【解决方案29】:

                            这是我使用的,它可能不是超级快,但它紧凑而简单:

                            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

                            【讨论】:

                              【解决方案30】:

                              使用来自 lodash 的块

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

                              【讨论】:

                                猜你喜欢
                                • 2013-06-27
                                • 1970-01-01
                                • 1970-01-01
                                • 2014-12-22
                                • 1970-01-01
                                • 2017-01-18
                                相关资源
                                最近更新 更多