I have a product form which I would like users to add variants of this product to. My object for the main settings
{
title: \'Bike\',
settings: {
opt
You can create an array of title
and a 2D array of values
array using map
. Then create a Cartesian product of all the values
. Then loop through the all the combinations and create objects using reduce
. Use { Image: "img.png" }
as the initialValue
parameter. This will work for any number of objects inside options
array
const input = { title: 'Bike', settings: { options: [{ title: 'Size', values: ['60cm', '80cm', '120cm'] }, { title: 'Color', values: ['White', 'Black', 'Red'] }], variants: [] } }
const { options } = input.settings,
titles = options.map(o => o.title),
values = options.map(o => o.values),
defaultObject = { Image: "img.png" }
// https://stackoverflow.com/a/57597533/3082296
const combos = values.reduce((acc, curr, i) =>
acc.flatMap(c => curr.map(n => [].concat(c, n)))
)
const createObject = values =>
titles.reduce((acc, k, i) => {
acc[k] = values[i];
return acc
}, defaultObject)
const output = combos.map(createObject)
console.log(...output)
Try this:
generateVariants() {
const options = [...this._form.settings.options];
const sizeOptions = options[0].values;
const colorOptions = options[1].values;
const regeneratedVariants = [];
for(let i=0;i< sizeOptions.length;i++) {
for(let j=0;j< colorOptions.length;j++) {
regeneratedVariants.push({
Size: sizeOptions[i],
Color: colorOptions[i],
Image: "img.png"
})
}
}
console.log(regeneratedVariants);
}
this will produce an array with all the variants possible with sizes and colors.
You could take the keys and values from data, generate the cartesian product from values and create key/value pairs as result.
var data = { title: 'Bike', settings: { options: [{ title: 'Size', values: ['60cm', '80cm', '120cm'] }, { title: 'Color', values: ['White', 'Black', 'Red'] }], variants: [] } },
keys = data.settings.options.map(({ title }) => title).concat('Image'),
values = data.settings.options.map(({ values }) => values).concat([['img.png']]),
cartesian = values
.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []))
.map(a => Object.assign({ title: a.slice(0, -1).join('/') }, ...keys.map((k, i) => ({ [k]: a[i] }))));
console.log(cartesian);
.as-console-wrapper { max-height: 100% !important; top: 0; }