Перебрать все матричные варианты (все возможные варианты)

Сначала я пытался сделать это сам, но то что у меня получается как результат меня не устраивает.

У меня есть массив данных следующего вида:

var data = {
  a: [1, 2, 3],
  b: ['a', 'b'],
  c: ['x', 'y', 'z'],
};

Я хочу получить что-то вроде:

a=1 b=a c=x
a=2 b=a c=x
a=3 b=a c=x
a=1 b=b c=x
a=2 b=b c=x
a=3 b=b c=x
a=1 b=a c=y
a=2 b=a c=y
a=3 b=a c=y
a=1 b=b c=y
a=2 b=b c=y
a=3 b=b c=y
a=1 b=a c=z
a=2 b=a c=z
a=3 b=a c=z
a=1 b=b c=z
a=2 b=b c=z
a=3 b=b c=z

Таким образом перебрав все возможные варианты. Предполагаю это должно решаться как-то просто, вероятно с помощью рекурсии. Однако мой код слишком большой и имеет ограничения по количеству вариантов (элементов объекта). В данном примере 18 вариантов полученных перемножением количества элементов массива 3 * 2 * 3


Ответы (1 шт):

Автор решения: vsemozhebuty

Насколько я понимаю, вам нужен алгоритм Cartesian Product:

https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sets/cartesian-product

https://github.com/mgechev/javascript-algorithms/blob/master/src/combinatorics/cartesianproduct.js

Если немного адаптировать вариант по второй ссылке (по первой есть пример вычисления только для двух наборов, по второй для неограниченного количества наборов), получается что-то вроде этого (если вам нужен другой формат результата, дайте, пожалуйста, пример того, что должно получится в виде кода):

var data = {
  a: [1, 2, 3],
  b: ['a', 'b'],
  c: ['x', 'y', 'z'],
};

function getCartesianProduct(sets) {
  const result = [];

  function cartesianProduct(sets, index, current) {
    if (index === sets.length) {
      result.push(current.slice());
      return;
    }
    for (let i = 0; i < sets[index].length; i++) {
      current[index] = sets[index][i];
      cartesianProduct(sets, index + 1, current);
    }
  }

  cartesianProduct(sets, 0, []);
  return result;
}

console.log(getCartesianProduct(Object.values(data)));

UPD. С другим порядком перебора:

var data = {
  a: [1, 2, 3],
  b: ['a', 'b'],
  c: ['x', 'y', 'z'],
};

function getCartesianProduct(sets) {
  const result = [];

  function cartesianProduct(sets, index, current) {
    if (index === sets.length) {
      result.push(current.slice().reverse());
      return;
    }
    for (let i = 0; i < sets[index].length; i++) {
      current[index] = sets[index][i];
      cartesianProduct(sets, index + 1, current);
    }
  }

  cartesianProduct(sets, 0, []);
  return result;
}

console.log(getCartesianProduct(Object.values(data).reverse()));

→ Ссылка