【问题标题】:How do you split an array into array pairs in JavaScript?如何在 JavaScript 中将数组拆分为数组对?
【发布时间】:2015-07-11 00:16:35
【问题描述】:

我想将一个数组拆分成数组对。

var arr = [2, 3, 4, 5, 6, 4, 3, 5, 5]

var newarr = [
    [2, 3],
    [4, 5],
    [6, 4],
    [3, 5],
    [5]
]

【问题讨论】:

标签: javascript arrays


【解决方案1】:

可以使用jsreduce

initialArray.reduce(function(result, value, index, array) {
  if (index % 2 === 0)
    result.push(array.slice(index, index + 2));
  return result;
}, []);

【讨论】:

  • 不会比这更短,最好的方法在这里! (并且没有额外的库)
  • 请务必注意很容易忘记的 initialValue(“[]”) - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 或者你可以使用一个扩展运算符,几乎是一个单行:D array.reduce((result, value, index, sourceArray) => index % 2 === 0 ? [...result, sourceArray.slice(index, index + 2)] : result, [])
【解决方案2】:

Lodash 对此有一个方法:https://lodash.com/docs/4.17.10#chunk

_.chunk([2,3,4,5,6,4,3,5,5], 2); // => [[2,3],[4,5],[6,4],[3,5],[5]]

【讨论】:

    【解决方案3】:

    没有预先烘焙的功能可以做到这一点,但这里有一个简单的解决方案:

    var splitPairs = function(arr) {
        var pairs = [];
        for (var i=0 ; i<arr.length ; i+=2) {
            if (arr[i+1] !== undefined) {
                pairs.push ([arr[i], arr[i+1]]);
            } else {
                pairs.push ([arr[i]]);
            }
        }
        return pairs;
    };
    

    【讨论】:

    • OP 显示的 arr 的奇数长度如何?
    • 很好,我针对这种情况修改了我的代码。谢谢
    • 看起来您在第一个推送语句中缺少右括号
    • 以防万一有人为此结束:我遇到了无限循环,因为我做了for(var i = 0; i &lt; arr.length; i + 2)。索引未更新,因为 i + 2 未设置 i 值。 i += 2 有效,因为它设置了 i 值。这就是为什么尽可能使用 map/reduce 更好地实现功能!
    【解决方案4】:

    另一个是已经发布的答案的混搭。添加它是因为阅读了答案后我仍然觉得事情可能更容易阅读:

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

    【讨论】:

    • 干得好,我觉得这个最容易理解。
    • 很好的解决方案。文档:slice:如果end 大于序列的长度,slice 会一直提取到序列的末尾(arr.length)。
    • 感谢您分享您的解决方案!
    • 3 年后,你帮助别人了!
    【解决方案5】:

    对于这种情况,我会使用lodash

    这是使用_.reduce的解决方案:

    var newArr = _(arr).reduce(function(result, value, index) {
      if (index % 2 === 0)
        result.push(arr.slice(index, index + 2));
    
      return result;
    }, []);
    

    var arr = [2,3,4,5,6,4,3,5,5];
    
    var newArr = _(arr).reduce(function(result, value, index) {
      if (index % 2 === 0)
        result.push(arr.slice(index, index + 2));
      
      return result;
    }, []);
    
    document.write(JSON.stringify(newArr)); // [[2,3],[4,5],[6,4],[3,5],[5]]
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"&gt;&lt;/script&gt;

    【讨论】:

    【解决方案6】:

    可以在一行中将数​​组分组为对/块,而无需库:

    function chunks(arr, size = 2) {
      return arr.map((x, i) => i % size == 0 && arr.slice(i, i + size)).filter(x => x)
    }
    console.log(chunks([1, 2, 3, 4, 5, 6, 7])) // -> [[1, 2], [3, 4], [5, 6], [7]]

    【讨论】:

      【解决方案7】:

      现在有灵活的Array#flatMap(value, index, array)

      const pairs = arr.flatMap((_, i, a) => i % 2 ? [] : [a.slice(i, i + 2)]);
      

      还有可能更高效但看起来很傻的Array.from(source, mapfn?)

      const pairs = Array.from({ length: arr.length / 2 }, (_, i) => arr.slice(i * 2, i * 2 + 2))
      

      【讨论】:

        【解决方案8】:

        与使用for 循环进行比较的方法略有不同。为了避免修改原始数组slice,由于 JS 通过引用传递对象,因此进行了浅拷贝。

        function pairArray(a) {
          var temp = a.slice();
          var arr = [];
        
          while (temp.length) {
            arr.push(temp.splice(0,2));
          }
        
          return arr;
        }
        

        var array = [2,3,4,5,6,4,3,5,5];
        var newArr = pairArray(array);
        
        function pairArray(a) {
          var temp = a.slice();
          var arr = [];
        
          while (temp.length) {
            arr.push(temp.splice(0,2));
          }
        
          return arr;
        }
        
        document.write('<pre>' + JSON.stringify(newArr) + '</pre>');

        【讨论】:

        • 哈哈,我看你不喜欢像我一样使用格式;)
        • @PatrickRobert 是的,在这种情况下,我意识到这让阅读变得更加困难。我想类似的想法。 :)
        【解决方案9】:

        这是一个很好的通用解决方案:

        function splitInto(array, size, inplace) {
            var output, i, group;
        
            if (inplace) {
                output = array;
        
                for (i = 0; i < array.length; i++) {
                    group = array.splice(i, size);
        
                    output.splice(i, 0, group);
                }
            } else {
                output = [];
        
                for (i = 0; i < array.length; i += size) {
                    output.push(array.slice(i, size + i));
                }
            }
        
            return output;
        }
        

        对于你的情况,你可以这样称呼它:

        var arr= [2,3,4,5,6,4,3,5,5];
        var newarr = splitInto(arr, 2);
        

        inplace 参数确定操作是否就地完成。

        下面是一个演示:

        function splitInto(array, size, inplace) {
            var output, i, group;
        
            if (inplace) {
                output = array;
        
                for (i = 0; i < array.length; i++) {
                    group = array.splice(i, size);
        
                    output.splice(i, 0, group);
                }
            } else {
                output = [];
        
                for (i = 0; i < array.length; i += size) {
                    output.push(array.slice(i, size + i));
                }
            }
        
            return output;
        }
        
        var arr= [2,3,4,5,6,4,3,5,5];
        var newarr = splitInto(arr, 2);
        
        disp(newarr);
        
        // or we can do it in-place...
        splitInto(arr, 3, true);
        
        disp(arr);
        
        function disp(array) {  
          var json = JSON.stringify(array);
        
          var text = document.createTextNode(json);
          var pre = document.createElement('pre');
        
          pre.appendChild(text);
          document.body.appendChild(pre);
        }

        【讨论】:

          【解决方案10】:

          这是另一个使用 lodash 助手的解决方案:

          function toPairs(array) {
            const evens = array.filter((o, i) => i % 2);
            const odds = array.filter((o, i) => !(i % 2));
            return _.zipWith(evens, odds, (e, o) => e ? [o, e] : [o]);
          }
          console.log(toPairs([2,3,4,5,6,4,3,5,5]));
          &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"&gt;&lt;/script&gt;

          【讨论】:

          【解决方案11】:

          const items = [1, 2, 3, 4, 5];
          
          const createBucket = (bucketItems, bucketSize) => buckets => {
            return bucketItems.length === 0 ? buckets : [...buckets, bucketItems.splice(0, bucketSize)];
          };
          
          const bucketWithItems = items.reduce(createBucket([...items], 4), []);

          【讨论】:

            【解决方案12】:

            这是一个简短且更通用的解决方案:

            function splitArrayIntoPairs(arr, n) {
             var len = arr.length
              var pairs = []
            
              for (let i = 0; i < len; i += n) {
                var temp = []
                for (var j = i; j < (i + n); j++) {
                  if (arr[j] !== undefined) {
                    temp.push(arr[j])
                  }
                }
                pairs.push(temp)
              }
              return pairs
            }
            

            其中 arr 是您的数组,而 n 不是对

            【讨论】:

              【解决方案13】:

              这是另一个使用生成器函数的通用解决方案。

              /**
               * Returns a `Generator` of all unique pairs of elements from the given `iterable`.
               * @param iterable The collection of which to find all unique element pairs.
               */
              function* pairs(iterable) {
                  const seenItems = new Set();
                  for (const currentItem of iterable) {
                      if (!seenItems.has(currentItem)) {
                          for (const seenItem of seenItems) {
                              yield [seenItem, currentItem];
                          }
                          seenItems.add(currentItem);
                      }
                  }
              }
              
              const numbers = [1, 2, 3, 2];
              const pairsOfNumbers = pairs(numbers);
              
              console.log(Array.from(pairsOfNumbers));
              // [[1,2],[1,3],[2,3]]

              我喜欢这种方法的一点是,它不会消耗输入中的下一个项目,直到它真正需要它。如果您将生成器作为输入提供给它,这将特别方便,因为它会尊重其延迟执行。

              【讨论】:

                【解决方案14】:

                这结合了上面的一些答案,但没有 Object.fromEntires。输出类似于 minimist 的输出。

                    const splitParameters = (args) => {
                      const split = (arg) => (arg.includes("=") ? arg.split("=") : [arg]);
                    
                      return args.reduce((params, arg) => [...params, ...split(arg)], []);
                    };
                    
                    const createPairs = (args) =>
                      Array.from({ length: args.length / 2 }, (_, i) =>
                        args.slice(i * 2, i * 2 + 2)
                      );
                    
                    const createParameters = (pairs) =>
                      pairs.reduce(
                        (flags, value) => ({
                          ...flags,
                          ...{ [value[0].replace("--", "")]: value[1] }
                        }),
                        {}
                      );
                    
                    const getCliParameters = (args) => {
                      const pairs = createPairs(splitParameters(args));
                      const paramaters = createParameters(pairs);
                    
                      console.log(paramaters);
                    
                      return paramaters;
                    };
                 
                
                    //const argsFromNodeCli = process.argv.slice(2); // For node
                      
                    const testArgs = [
                      "--url",
                      "https://www.google.com",
                      "--phrases=hello,hi,bye,ok"
                    ];
                    
                    const output = getCliParameters(testArgs);
                    document.body.innerText = JSON.stringify(output);

                【讨论】:

                  猜你喜欢
                  • 2022-07-06
                  • 2016-03-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-10-16
                  • 2018-01-02
                  • 2016-12-11
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多