Перебрать все матричные варианты (все возможные варианты)
Сначала я пытался сделать это сам, но то что у меня получается как результат меня не устраивает.
У меня есть массив данных следующего вида:
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 шт):
Насколько я понимаю, вам нужен алгоритм 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()));