0

Lets say that we have 2 arrays we want to return one array that contains each array1[element] + ( rest of elements in array 2 ) and so on.

let array1 = ["a","b"];
let array2 = ["e","f"];

let array3 = mergeArrays(array1,array2);// ["ae","af","be","bf"]

// I tried something like this

let output = [];
let x = 0;
for (let i = 0;i< variants.length;i++){
   for (let j = 0;j < variants[i].length;j++){
       output[x] = variants[i][x] + variants[j][x];
       x++;
   }
}
  • Possible duplicate of [How to merge two arrays in JavaScript and de-duplicate items](https://stackoverflow.com/questions/1584370/how-to-merge-two-arrays-in-javascript-and-de-duplicate-items) – Lee Taylor Sep 17 '19 at 21:28
  • 2
    @LeeTaylor no, it's a different problem. This one is about Cartesian product, the one you linked to is about union. – mbojko Sep 17 '19 at 21:30

4 Answers4

3

With two maps and flattening:

let array1 = ["a","b"];
let array2 = ["e","f"];

let array3 = array1.map(a => array2.map(b => a + b)).flat();
console.log(array3);
mbojko
  • 13,503
  • 1
  • 16
  • 26
  • Cool one. But remember about [this](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat). I have recently used `Array.prototype.flat` and was surprised with Samsung Browser – Tomasz Bubała Sep 17 '19 at 21:42
2

You can simply use nested for (...of) loops to generate the Cartesian product of two arrays:

let array1 = ["a", "b"];
let array2 = ["e", "f"];

function mergeArrays(arr1, arr2) {
  let res = [];
  for (i of arr1) {
    for (j of arr2) {
      res.push(i + j);
    }
  }
  return res;
}

let array3 = mergeArrays(array1, array2);

console.log(array3);
DjaouadNM
  • 22,013
  • 4
  • 33
  • 55
2

Even shorter than mbojko's answer:

let array1 = ["a","b"];
let array2 = ["e","f"];
let array3 = array1.flatMap(a => array2.map(b => a + b));

console.log(array3);

This uses the Array.prototype.flatMap() method.


In fact, you can extend this to support any number of arrays:

function cartesian (reducerFn) {
  return function zip (array, ...arrays) {
    if (arrays.length === 0) return array;

    const values = zip(...arrays);
    return array.flatMap(a => values.map(b => reducerFn(a, b)));
  };
}

const mergeArrays = cartesian((a, b) => a + b);

let array1 = ["a","b"];
let array2 = ["c","d"];
let array3 = ["e","f"];
let array4 = mergeArrays(array1, array2, array3);

console.log(array4);
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • This is great , I already done this hard coded because I just have three arrays so I just merged the first 2 arrays then the last one. but your solution is more dynamic :) – Mohanad Inairat Sep 17 '19 at 22:47
1

Using ES6:

const array1 = ["a","b"];
const array2 = ["e","f"];

const result = array1.reduce((acc, curr) => {
  const product = array2.map(el => curr + el);
  acc.push(...product)
  return acc;
}, []);

console.log(result);

Loop through first array with Array.prototype.reduce and foreach item get the product with second array, push to accumulator and repeat for each element in first array to get the result.

To make concatenation more predictable (in case of input other than string) I'd use ` ${curr}${el} ` instead of curr + el. It's up to your needs though!

Tomasz Bubała
  • 2,093
  • 1
  • 11
  • 18