如何在JavaScript数组中查找元素的所有组合

时间:2014-09-10 14:47:07

标签: javascript arrays combinations

我有以下数组:

[[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]]

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

我不确定从哪里开始,所以任何建议或指示都会非常有用!

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

试试这个:

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

答案 2 :(得分:0)

让我们分解问题。首先,让我们解决每个子阵列的第一个元素:

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循环的双元素数组元素。
  5. 是的,这不是你母亲的JavaScript。它几乎与你初始化它的样式语言不同,并设置它并循环到另一个东西并返回其他东西。通过采用这种风格,我们最终得到的代码更精确,更简洁,可重复使用,可证明正确,适合未来,并且可能是可优化的。

    对于未来友好,我的意思是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);