2

given two arrays (of unknown size) like so:

var first = ['A1','A2','A3'];
var second= ['B1','B2'];

I want to get set of all possible pairs from those arrays. In above example proper result should look like this:

var result = [['A1B1','A2B2'], ['A1B1','A3B2'],['A1B2','A2B1'],['A1B2','A3B1'],['A2B1','A3B2'],['A2B2','A3B1']];

I tried to come up with solution on my own, but I am stuck in increasingly bigger numer of nested loops...

EDIT:

Sorry, perhaps I wasn't that clear when forming my question. Maybe it would be easier on an example - let's assume that first array contains names of truck drivers, and second array contains cities. Each driver can only drive to one city, and each city can only be visited by single driver.

In this scenario expected output of the function would be a complete list of possible combinations (driver + city). Unknown lengths of input arrays obviously means that there may be drivers that won't drive anywhere, and there might be cities which won't get visited by any driver.

I hope now my question is more clear now.

EDIT2:

I don't think this is a duplicate of Finding all possible value combinations between two arrays since accepted answer in that question works only (if I understand it correctly) for second array of length 2.

siwy2411
  • 51
  • 1
  • 9
  • 2
    why does your result not contain `['A1B1', 'A2B1']` – Ayush Gupta Jan 14 '18 at 16:25
  • Why would you need an "increasingly bigger numer of nested loops" to get result? Can you include the code that you have tried to resolve inquiry at the Question? See https://stackoverflow.com/help/mcve – guest271314 Jan 14 '18 at 16:34
  • _"In above example proper result should look like this: `var result = [['A1B1','A2B2'], ['A1B1','A3B2'],['A1B2','A2B1'],['A1B2','A3B1'],['A2B1','A3B2'],['A2B2','A3B1']];`"_ Is the expected `.length` of the resulting array `6`? – guest271314 Jan 14 '18 at 17:01
  • I don't quite understand why the result is structured this way. – Felix Kling Jan 14 '18 at 17:26
  • 1
    there are 6 AB combo's, in pairs this becomes 36, so how do we know what you mean? – JMP Jan 14 '18 at 17:30
  • I edited my question - I hope now it will be more clear what I try to achieve – siwy2411 Jan 14 '18 at 21:12

2 Answers2

1

Rewriting the answer to handle arrays of arbitrary length.

The trick here is, since every element of the shorter array is going to be used once in each pairing, you can just leave it in order as the first half of each pair. Then permute the second array around it, discarding any leftover elements, to get all the possible combinations:

var permute = function(arr) {
  // returns an array containing every permutation of the input array
  var permutations = [];
  if (arr.length === 1) return [arr];
  for (var i = 0; i < arr.length; i++) {
    var subPerms = permute(arr.slice(0, i).concat(arr.slice(i + 1)));
    for (var j = 0; j < subPerms.length; j++) {
      subPerms[j].unshift(arr[i]);
      permutations.push(subPerms[j]);
    }
  }
  return permutations;
}

var pairs = function(in1, in2) {
  if (in1.length > in2.length) return pairs(in2, in1); // swap the arrays if the longer one was first

  var out = [];
  var permutations = permute(in2);

  for (var i = 0; i < permutations.length; i++) {
    var subarr = permutations[i];

    subarr.length = in1.length; // drop extras
    for (var j = 0; j < in1.length; j++) {
      subarr[j] = in1[j] + subarr[j] // match up the shorter array to this arrangement
    }
    out.push(subarr);
  }
  return out;
}

var first = ['A1', 'A2', 'A3'];
var second = ['B1', 'B2','B3'];
console.log(pairs(first, second))
.as-console-wrapper {
  max-height: 100% !important
}
Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
  • This response is good in dealing with data which i gave as example, but it fails for longer arrays (ie. adding 'B3' to second array). But then again, this might be my fault in stating the problem in my question. I edited my question, hope it's more clear right now. – siwy2411 Jan 14 '18 at 21:15
  • I'm not sure how this fails on longer arrays? With three items in each array, this returns 18 pairs; does that exclude some that should be included or vice versa? Your edited explanation honestly doesn't clarify what you expect here. – Daniel Beck Jan 14 '18 at 21:24
  • Ooooh, hang on, I think I see, with three items in each array you'd want results like `[[A1B1,A2B2,A3B3],[A1B2,A2B1,A3B3],[A1B3,A2B1,A3B2]...]` is that the idea? – Daniel Beck Jan 14 '18 at 21:38
  • exactly - that's the expected output! – siwy2411 Jan 14 '18 at 22:23
  • @siwy2411 Ok, revised the answer... I think this does what you need? – Daniel Beck Jan 15 '18 at 00:18
  • Yes, thank you very much :) – siwy2411 Jan 16 '18 at 07:42
-1

You have to use two loops, you cannot escape that, and the function is something like this:

var combinationOf = function(one, two) { 
 var res = [];
 first.forEach((a) => {
   second.forEach((b) => {
     res.push(a + b);
   });
 });
 return res;
}