Как преобразовать данные объекта в другой объект?
При заполнении пользователем информации о товаре, объект получается вот такого вида:
SendData: {
Description: 'Крутые кроссовки Nike Air',
Name: 'Кроссовки Nike',
Options: {
Colors: [ 'Красный', 'Синий' ],
Sizes: [ '36', '37' ],
},
Price: 5000,
VendorCode: 'Nike01'
}
Опций кроме Colors и Size может быть еще, и данных в массивах Colors и Size больше. Как при всем этом при заполнении всех полей получать подобный массив объектов
[
{
VendorCode: 'Nike01-Красный-36',
Color: 'Красный',
Size: '36',
},
... и так далее, пока не переберутся все возможные комбинации
]
Как это реализовать на JS?
Ответы (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
Если немного адаптировать вариант по второй ссылке (по первой есть пример вычисления только для двух наборов, по второй для неограниченного количества наборов), получается что-то вроде этого:
const data = {
SendData: {
Description: 'Крутые кроссовки Nike Air',
Name: 'Кроссовки Nike',
Options: {
Colors: ['Красный', 'Синий'],
Sizes: ['36', '37'],
Foo: ['bar', 'baz'],
},
Price: 5000,
VendorCode: 'Nike01',
},
};
const optionNames = Object.keys(data.SendData.Options);
const optionSets = getCartesianProduct(Object.values(data.SendData.Options));
const variants = optionSets.map(
set => Object.fromEntries([
['VendorCode', `${data.SendData.VendorCode}-${set.join('-')}`],
...optionNames.map((name, i) => [name, set[i]]),
])
);
console.log(variants);
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;
}