0

I have the following array:

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

I want to be able to get all combinations of the first index of each sub array and then loop through those combinations performing a single task on each. So these are the combinations I'm after (Note I need the combination of the same value as well):

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

I'd then loop through that and do something with each of the values.

I'm not sure where even to start here so any advice or pointers would be really helpful!

3 Answers 3

1

You need to effectively loop through the array twice. Based on what you want you can just statically access the first element each time:

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

Sign up to request clarification or add additional context in comments.

Comments

0

Try this:

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

Here is the jsfiddle-demo

Comments

0

Let's decompose the problem. First, let's get extracting the first element of each subarray out of the way:

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

So

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

Decomposing the problem like this is fundamental to good program design. We don't want to write things which jumble up multiple problems. In this case, the multiple problems are (1) getting the first element of each subarray and (2) finding the combinations. If we write one routine which mixes up the two problems, then we will never be able to re-use it for other things. If our boss comes and says now he wants to find all the combinations of the second element of each subarray, we'll have to cut and paste and create nearly duplicate code. Then we'll be maintaining that code for the rest of our lives or at least until we quit. The rule about factoring is do it sooner rather than later.

Then, create all combinations of any two arrays:

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

Normally we would write this more compactly. Let's walk through it:

  1. Array#concat combines one or more things, or elements inside those things if they are arrays, into an array.
  2. Function#apply lets us provide an array that will turn into the argument list of concat.
  3. Array#map creates a parallel array to arr1, which contains...
  4. elements which are two-element arrays based on looping over arr2.

Right, this is not your mother's JavaScript. It's almost a different language from the style where you initialize this and set that and loop over the other thing and return something else. By adopting this style, we end up with code which is more precise, concise, reusable, provably correct, future-friendly, and maybe optimizable.

By future-friendly, I mean among other things ES6-friendly. The above could be rewritten as:

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

Get ready guys and girls, this will come up in your job interviews pretty soon now. Time to move on from jQuery.

Now the problem can be expressed as:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.