Как преобразовать данные объекта в другой объект?

При заполнении пользователем информации о товаре, объект получается вот такого вида:

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 шт):

Автор решения: 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

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

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;
}

→ Ссылка