【问题标题】:How to split a long array into smaller arrays, with JavaScript如何使用 JavaScript 将长数组拆分为更小的数组
【发布时间】:2023-03-05 03:38:01
【问题描述】:

我有一个电子邮件数组(可以是 1 封电子邮件,也可以是 100 封电子邮件),我需要使用 ajax 请求发送数组(我知道该怎么做),但我只能发送一个包含 10 封或更少电子邮件的数组。因此,如果有一个包含 20 封电子邮件的原始阵列,我需要将它们分成 2 个阵列,每个阵列 10 个。或者如果原始数组中有 15 封电子邮件,然后是 1 个 10 个数组,另一个数组 5 个。我正在使用 jQuery,最好的方法是什么?

【问题讨论】:

    标签: javascript jquery arrays loops


    【解决方案1】:

    不要使用 jquery...使用纯 javascript

    var a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
    
    var b = a.splice(0,10);
    
    //a is now [11,12,13,14,15];
    //b is now [1,2,3,4,5,6,7,8,9,10];
    

    你可以循环这个以获得你想要的行为。

    var a = YOUR_ARRAY;
    while(a.length) {
        console.log(a.splice(0,10));
    }
    

    这一次会给你 10 个元素...如果你说 15 个元素,你会得到 1-10,11-15 是你想要的。

    【讨论】:

    • 请注意,YOUR_ARRAY 也会被消耗(数组是对象...)
    • 是的,我之所以这么说是因为 a 是非描述性的,而且我已经使用 a 编写了示例...这是完全不必要的代码行...虽然,这让我觉得...如果使用此模式,您可能希望将深层复制到工作数组中,以免破坏您的原始
    • @junvar IDK 如果该 1-liner 在 2018 年有效(我严重怀疑它是否有效),但它今天惨遭失败。你应该永远改变(即删除元素)一个被迭代的数组,它会抛出索引,即在每次删除后它应该根据删除的元素数量重新调整,所以它“向前跳过” " 并且不完全消耗数组。 Try it
    【解决方案2】:
    var size = 10; var arrayOfArrays = [];
    for (var i=0; i<bigarray.length; i+=size) {
         arrayOfArrays.push(bigarray.slice(i,i+size));
    }
    console.log(arrayOfArrays);
    

    splice() 不同,slice() 不会破坏原始数组。

    【讨论】:

    • 这个方案更好
    • 应该是 i+size 而不是 i+=size
    【解决方案3】:

    只需遍历数组,将其拼接直到全部消耗完。

    
    
    var a = ['a','b','c','d','e','f','g']
      , chunk
    
    while (a.length > 0) {
    
      chunk = a.splice(0,3)
    
      console.log(chunk)
    
    }
    
    

    输出

    
    [ 'a', 'b', 'c' ]
    [ 'd', 'e', 'f' ]
    [ 'g' ]
    
    

    【讨论】:

      【解决方案4】:

      你可以使用 lodash: https://lodash.com/docs

      _.chunk(['a', 'b', 'c', 'd'], 2);
      // → [['a', 'b'], ['c', 'd']]
      

      【讨论】:

        【解决方案5】:

        Array.reduce 对于大型数组可能效率低下,尤其是使用 mod 运算符。我认为一个更简洁(可能更容易阅读)的功能解决方案是这样的:

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

        【讨论】:

          【解决方案6】:

          假设您不想破坏原始数组,您可以使用这样的代码将长数组分解为更小的数组,然后您可以对其进行迭代:

          var longArray = [];   // assume this has 100 or more email addresses in it
          var shortArrays = [], i, len;
          
          for (i = 0, len = longArray.length; i < len; i += 10) {
              shortArrays.push(longArray.slice(i, i + 10));
          }
          
          // now you can iterate over shortArrays which is an 
          // array of arrays where each array has 10 or fewer 
          // of the original email addresses in it
          
          for (i = 0, len = shortArrays.length; i < len; i++) {
              // shortArrays[i] is an array of email addresss of 10 or less
          }
          

          【讨论】:

            【解决方案7】:

            作为@jyore 的answer 的补充,如果你还想保留原来的数组:

            var originalArray = [1,2,3,4,5,6,7,8];
            
            var splitArray = function (arr, size) {
            
              var arr2 = arr.slice(0),
                  arrays = [];
            
              while (arr2.length > 0) {
                  arrays.push(arr2.splice(0, size));
              }
            
              return arrays;
            }
            
            splitArray(originalArray, 2);
            // originalArray is still = [1,2,3,4,5,6,7,8];
            

            【讨论】:

              【解决方案8】:

              另一种实现:

              const arr = ["H", "o", "w", " ", "t", "o", " ", "s", "p", "l", "i", "t", " ", "a", " ", "l", "o", "n", "g", " ", "a", "r", "r", "a", "y", " ", "i", "n", "t", "o", " ", "s", "m", "a", "l", "l", "e", "r", " ", "a", "r", "r", "a", "y", "s", ",", " ", "w", "i", "t", "h", " ", "J", "a", "v", "a", "S", "c", "r", "i", "p", "t"];
              
              const size = 3; 
              const res = arr.reduce((acc, curr, i) => {
                if ( !(i % size)  ) {    // if index is 0 or can be divided by the `size`...
                  acc.push(arr.slice(i, i + size));   // ..push a chunk of the original array to the accumulator
                }
                return acc;
              }, []);
              
              // => [["H", "o", "w"], [" ", "t", "o"], [" ", "s", "p"], ["l", "i", "t"], [" ", "a", " "], ["l", "o", "n"], ["g", " ", "a"], ["r", "r", "a"], ["y", " ", "i"], ["n", "t", "o"], [" ", "s", "m"], ["a", "l", "l"], ["e", "r", " "], ["a", "r", "r"], ["a", "y", "s"], [",", " ", "w"], ["i", "t", "h"], [" ", "J", "a"], ["v", "a", "S"], ["c", "r", "i"], ["p", "t"]]
              

              注意 - 这不会修改原始数组。

              或者,如果您更喜欢功能性、100% 不可变(尽管像上面所做的那样在适当位置进行变异确实没有什么坏处)和自包含方法:

              function splitBy(size, list) {
                return list.reduce((acc, curr, i, self) => {
                  if ( !(i % size)  ) {  
                    return [
                        ...acc,
                        self.slice(i, i + size),
                      ];
                  }
                  return acc;
                }, []);
              }
              

              【讨论】:

                【解决方案9】:

                我也想分享我的解决方案。它有点冗长,但也很有效。

                var data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
                
                var chunksize = 4;
                
                
                var chunks = [];
                
                data.forEach((item)=>{
                  if(!chunks.length || chunks[chunks.length-1].length == chunksize)
                  chunks.push([]);
                
                  chunks[chunks.length-1].push(item);
                });
                
                console.log(chunks);
                

                输出(格式化):

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

                【讨论】:

                  【解决方案10】:

                  另一种方法:

                  var longArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
                  var size = 2;
                  
                  var newArray = new Array(Math.ceil(longArray.length / size)).fill("")
                      .map(function() { return this.splice(0, size) }, longArray.slice());
                  
                  // newArray = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]];
                  

                  这不会影响原始数组,因为使用 slice 制作的副本被传递到 map 的 'this' 参数中。

                  【讨论】:

                    【解决方案11】:

                    另一种实现,使用 Array.reduce(我认为这是唯一缺少的!):

                    const splitArray = (arr, size) =>
                    {
                        if (size === 0) {
                            return [];
                        }
                    
                        return arr.reduce((split, element, index) => {
                            index % size === 0 ? split.push([element]) : split[Math.floor(index / size)].push(element);
                            return split;
                        }, []);
                    };
                    

                    与上面的许多解决方案一样,这个是非破坏性的。当大小为 0 时返回一个空数组只是一个约定。如果if 块被省略,你会得到一个错误,这可能是你想要的。

                    【讨论】:

                      【解决方案12】:

                      更紧凑:

                      const chunk = (xs, size) =>
                        xs.map((_, i) =>
                          (i % size === 0 ? xs.slice(i, i + size) : null)).filter(Boolean);
                          
                      // Usage:
                      const sampleArray = new Array(33).fill(undefined).map((_, i) => i);
                      
                      console.log(chunk(sampleArray, 5));

                      【讨论】:

                        【解决方案13】:

                        您可以从一个空数组开始,然后在从原始数组中减去所需范围的部分,同时从原始数组中减去,直到为空。

                        const originalArr = [1,2,3,4,5,6,7,8,9,10,11];
                        const splittedArray = [];
                          while (originalArr.length > 0) {
                            splittedArray.push(originalArr.splice(0,range));  
                          }
                        

                        范围 3 的输出

                        splittedArray === [[1,2,3][4,5,6][7,8,9][10,11]]
                        

                        范围 4 的输出

                        splittedArray === [[1,2,3,4][5,6,7,8][9,10,11]]
                        

                        如果需要,这也适用于前置分页。

                        【讨论】:

                        • 能否添加一些描述?
                        【解决方案14】:

                        你可以看看这段代码。简单有效。

                        function chunkArrayInGroups(array, unit) {
                        var results = [],
                        length = Math.ceil(array.length / unit);
                        
                        for (var i = 0; i < length; i++) {
                            results.push(array.slice(i * unit, (i + 1) * unit));
                        }
                         return results;
                        }
                        
                        chunkArrayInGroups(["a", "b", "c", "d"], 2);
                        

                        【讨论】:

                          【解决方案15】:

                          这是一个简单的衬线

                          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);
                          console.log(segment(arr,7));

                          【讨论】:

                            【解决方案16】:
                            function chunkArrayInGroups(arr, size) {
                                var newArr=[];
                            
                                for (var i=0; i < arr.length; i+= size){
                                newArr.push(arr.slice(i,i+size));
                                }
                                return newArr;
                            
                            }
                            
                            chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3);
                            

                            【讨论】:

                            • 欢迎来到stackoverflow。添加一些解释会改善您的答案。
                            【解决方案17】:

                            作为一个函数

                            var arrayChunk = function (array, chunkSize) {
                                        var arrayOfArrays = [];
                            
                                        if (array.length <= chunkSize) {
                                            arrayOfArrays.push(array);
                                        } else {
                                            for (var i=0; i<array.length; i+=chunkSize) {
                                                arrayOfArrays.push(array.slice(i,i+chunkSize));
                                            }
                                        }
                                        return arrayOfArrays;
                                    }
                            

                            使用

                            arrayChunk(originalArray, 10) //10 being the chunk size.
                            

                            【讨论】:

                              【解决方案18】:

                              使用递归

                              let myArr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
                              let size = 4; //Math.sqrt(myArr.length); --> For a n x n matrix
                              let tempArr = [];
                              function createMatrix(arr, i) {
                                  if (arr.length !== 0) {
                                    if(i % size == 0) {
                                      tempArr.push(arr.splice(0,size))
                                    } 
                                    createMatrix(arr, i - 1)
                                  }
                              }
                              createMatrix(myArr, myArr.length);
                              console.log(tempArr);
                              

                              注意:现有数组即 myArr 将被修改。

                              【讨论】:

                                【解决方案19】:

                                使用原型我们可以直接设置为数组类

                                Array.prototype.chunk = function(n) {
                                  if (!this.length) {
                                    return [];
                                  }
                                  return [this.slice(0, n)].concat(this.slice(n).chunk(n));
                                };
                                console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].chunk(5));

                                【讨论】:

                                • 你能解释一下\给我来源这是如何工作的吗?
                                【解决方案20】:

                                如果你想要一个不修改现有数组的方法,试试这个:

                                let oldArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
                                let newArray = [];
                                let size = 3; // Size of chunks you are after
                                let j = 0; // This helps us keep track of the child arrays
                                
                                for (var i = 0; i < oldArray.length; i++) {
                                  if (i % size === 0) {
                                    j++
                                  }
                                  if(!newArray[j]) newArray[j] = [];
                                  newArray[j].push(oldArray[i])
                                }
                                

                                【讨论】:

                                  【解决方案21】:
                                  function chunkArrayInGroups(arr, size) {
                                      var newArr=[];
                                  
                                      for (var i=0; arr.length>size; i++){
                                      newArr.push(arr.splice(0,size));
                                      }
                                      newArr.push(arr.slice(0));
                                      return newArr;
                                  
                                  }
                                  
                                  chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3);
                                  

                                  【讨论】:

                                  • 别忘了做:newArr=[] 一个局部变量
                                  • 纯代码答案往往会被标记,然后因为质量低下而被删除。您能否就这如何解决最初的问题提供一些评论?
                                  • 如果块大小小于输入数组大小,这将不起作用。
                                  【解决方案22】:
                                  let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
                                  let size = 5;
                                  let fragments = Array.from(Array(Math.ceil(a.length / size))).map((_,index) => a.slice(index * size,(index + 1) * size))
                                  

                                  【讨论】:

                                  • 欢迎来到stackoverflow。添加一些解释会改善您的答案。
                                  • ReferenceError: a is not defined
                                  猜你喜欢
                                  • 1970-01-01
                                  • 2022-07-07
                                  • 2022-12-02
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2020-05-17
                                  • 2016-03-12
                                  • 2017-12-11
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多