【问题标题】:How to find all combinations of elements in JavaScript array如何在 JavaScript 数组中查找所有元素组合
【发布时间】:2014-09-10 14:47:06
【问题描述】:

我有以下数组:

[[A,1,X],[B,2,Y],[C,3,Z]]

我希望能够获得每个子数组的第一个索引的所有组合,然后循环遍历这些组合,在每个组合上执行单个任务。所以这些是我追求的组合(注意我也需要相同值的组合):

[[A,A],[A,B],[A,C],[B,A],[B,B],[B,C],[C,A],[C,B ],[C,C]]

然后我会遍历它并对每个值做一些事情。

我什至不知道从哪里开始,所以任何建议或指示都会很有帮助!

【问题讨论】:

    标签: javascript arrays combinations


    【解决方案1】:

    您需要有效地循环遍历数组两次。根据您的需要,您每次都可以静态访问第一个元素:

    var arr = [['A',1,'X'],['B',2,'Y'],['C',3,'Z']];
    var newArr = [];
    var length = arr.length;
    var curr;
    
    for (var i = 0; i < length; i++) {
        curr = arr[i][0];
    
        for (var j = 0; j < length; j++) {
            newArr.push([curr, arr[j][0]]);
        }
    }
    
    console.log(newArr);
    

    Fiddle

    【讨论】:

      【解决方案2】:

      试试这个:

      var data = [['A',1,'X'],['B',2,'Y'],['C',3,'Z']];
      
      function getCombinations(data) {
          var combinations = [];
          data.forEach(function(first) {
              data.forEach(function(second) {
                  combinations.push([first[0], second[0]]);
              });
          });
          return combinations;
      }
      
      console.log(getCombinations(data));
      

      这里是jsfiddle-demo

      【讨论】:

        【解决方案3】:

        让我们分解问题。首先,让我们提取每个子数组的第一个元素:

        function get_elts(data, idx) {
            return data.map(function(v) { return v[idx]; });
        }
        

        所以

        > get_elts(data, 0) // ['A', 'B', 'C']
        

        像这样分解问题是良好程序设计的基础。我们不想写混杂多个问题的东西。在这种情况下,多个问题是(1)获取每个子数组的第一个元素和(2)找到组合。如果我们编写一个将这两个问题混为一谈的例程,那么我们将永远无法将其重新用于其他事情。如果我们的老板现在说他想找到每个子数组的 second 元素的所有组合,我们将不得不剪切和粘贴并创建几乎重复的代码。然后我们将在我们的余生或至少在我们退出之前维护该代码。关于因式分解的规则是越早越好。

        然后,创建任意两个数组的所有组合:

        function combinations(arr1, arr2) {      //create all combos of elts in 2 arrays by
            return [].concat.apply(              //concatenating and flattening
                [],                              //(starting with an empty array)
                arr1.map(                        //a list created from arr1  
                    function(v1) {               //by taking each elt and from it
                        return arr2.map(         //creating a list from arr2
                            function(v2) {       //by taking each element and from it
                                return [v1, v2]; //making a pair with the first elt
                            }
                        );
                    };
                )
            );
        }
        

        通常我们会写得更紧凑。让我们来看看:

        1. Array#concat 将一个或多个事物或这些事物中的元素(如果它们是数组)组合成一个数组。
        2. Function#apply 让我们提供一个数组,该数组将变成concat 的参数列表。
        3. Array#map 为arr1 创建一个并行数组,其中包含...
        4. 元素是基于循环 arr2 的二元素数组。

        对,这不是你妈妈的 JavaScript。它与您初始化 this 并设置 that 并循环另一件事并返回其他内容的风格几乎是一种不同的语言。通过采用这种风格,我们最终得到的代码更加精确、简洁、可重用、可证明正确、面向未来并且可能可优化。

        对于未来友好,我的意思是对 ES6 友好。以上可以改写为:

        combinations = (arr1, arr2) => [].concat(...arr1.map(v1 => arr2.map(v2 => [v1, v2])));
        

        准备好男人和女孩,这很快就会出现在你的工作面试中。是时候从 jQuery 继续前进了。

        现在问题可以表示为:

        var first_elts = get_elts(data, 0);
        combinations(first_elts, first_elts);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-18
          • 1970-01-01
          • 2012-04-09
          相关资源
          最近更新 更多