Мне нужно сгенерировать полный набор вариантов на основе списка из N атрибутов, сохраняя при этом имя атрибута неповрежденным.Декартовы произведения объектов в javascript
var input = [
{ 'colour' : ['red', 'green'] },
{ 'material' : ['cotton', 'wool', 'silk'] },
{ 'shape' : ['round', 'square', 'rectangle'] }
];
var expected = [
{ 'colour': 'red', 'material': 'cotton', 'shape': 'round' },
{ 'colour': 'red', 'material': 'cotton', 'shape': 'square' },
{ 'colour': 'red', 'material': 'cotton', 'shape': 'rectangle' },
{ 'colour': 'red', 'material': 'wool', 'shape': 'round' },
{ 'colour': 'red', 'material': 'wool', 'shape': 'square' },
{ 'colour': 'red', 'material': 'wool', 'shape': 'rectangle' },
{ 'colour': 'red', 'material': 'silk', 'shape': 'round' },
{ 'colour': 'red', 'material': 'silk', 'shape': 'square' },
{ 'colour': 'red', 'material': 'silk', 'shape': 'rectangle' },
{ 'colour': 'green', 'material': 'cotton', 'shape': 'round' },
{ 'colour': 'green', 'material': 'cotton', 'shape': 'square' },
{ 'colour': 'green', 'material': 'cotton', 'shape': 'rectangle' },
{ 'colour': 'green', 'material': 'wool', 'shape': 'round' },
{ 'colour': 'green', 'material': 'wool', 'shape': 'square' },
{ 'colour': 'green', 'material': 'wool', 'shape': 'rectangle' },
{ 'colour': 'green', 'material': 'silk', 'shape': 'round' },
{ 'colour': 'green', 'material': 'silk', 'shape': 'square' },
{ 'colour': 'green', 'material': 'silk', 'shape': 'rectangle' }
];
Есть много алгоритмов вокруг для декартовых произведений массивов, но я не могу найти для объектов, сохраняющих ключи.
Производительность не вызывает большого беспокойства, так как для каждого атрибута никогда не будет более десятка значений. Заказ не должен точно соответствовать expected
.
Я сделал первую попытку на основе стандартных алгоритмов для списков, но я изо всех сил:
function cartesianProduct(input, current) {
if (!input || input.length < 1) {
return [];
}
var head = input[0];
var tail = input.slice(1);
var output = [];
for (var key in head) {
for (var i = 0; i < head[key].length; i++) {
if (typeof current == 'undefined') {
var current = {};
}
current[key] = head[key][i];
var productOfTail = cartesianProduct(tail, current);
output.push(current);
console.log(current);
}
}
return output;
}
console.log(cartesianProduct(input));
[аналогичный вопрос был здесь спросил] (http://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in -javascript) – Keithamus
В вашем коде есть большая проблема: вы не объявляете i как var, поэтому он считается глобальным var, следовательно, изменение d во внутренних вызовах функции ... – GameAlchemist