If I have an object parent like this, and an object with every field name is the ID which include the array like childs. How can I do to have clone the parent become children with different attritube as the result I mention below?
var parent = {
'Name': 'Product ABC',
}
var attributes = {
// AttributeId : Name
'ID0001': ['Black', 'Red'],
'ID0002': ['Small', 'Medium', 'Large'],
'ID0003': ['Cotton', 'Len']
}
The children cloned should be
{
'Name': 'Product ABC', // Same as parent
'Attributes': [ // Black - Small - Cotton
{'AttributeId':'ID0001', value:'Black'},
{'AttributeId':'ID0002', value:'Small'}
{'AttributeId':'ID0003', value:'Cotton'}
]
},
{
'Name': 'Product ABC', // Same as parent
'Attributes': [ // Red - Small - Cotton
{'AttributeId':'ID0001', value:'Red'},
{'AttributeId':'ID0002', value:'Small'}
{'AttributeId':'ID0003', value:'Cotton'}
]
},
{
'Name': 'Product ABC', // Same as parent
'Attributes': [ // Black - Medium - Cotton
{'AttributeId':'ID0001', value:'Black'},
{'AttributeId':'ID0002', value:'Medium'}
{'AttributeId':'ID0003', value:'Cotton'}
]
}
.....
P/S It seem to hard to understand the values rule of the children generated. Here is my description: children is cloned to become full of atributes in the 'attributes' object that include some arrays, but it unique atribute. like 'Black - Small - Cotton', 'Red - Small - Cotton', 'Black - Medium - Cotton', 'Black - Medium - Len', ...
CodePudding user response:
This looks like a Cartesian product that is then mapped later, so I have used this answer to get the Cartesian product of the attributes (read: "combinations"). Then I map over the resulting combinations and transform them into the desired structure.
const parent = {
'Name': 'Product ABC',
};
const children = {
'ID0001': ['Black', 'Red'],
'ID0002': ['Small', 'Medium', 'Large'],
'ID0003': ['Cotton', 'Len'],
};
const f = (a, b) => [].concat(...a.map(a => b.map(b => [].concat(a, b))));
const cartesian = (a, b, ...c) => b ? cartesian(f(a, b), ...c) : a;
function combinations(attributes) {
// restructure the given attributes
const choices = Object
.entries(attributes)
.map(([key, value]) => value.map((attr) => ({ [key]: attr })));
// get cartesian product of the choices
return cartesian(...choices);
}
const results = combinations(children).map((combo) => ({
...parent,
Attributes:
combo.map((o) => {
const key = Object.keys(o)[0]; // get only key
return {
AttributeId: key,
value: o[key],
};
}),
}));
console.log(results);
.as-console-wrapper { max-height: 100% !important }
CodePudding user response:
Here is some psuedocode that can hopefully get you started:
Just to be clear - this code is just an example of the logic you would need to do this. It is not actually finished code in a particular language. Actually writing code oneself in a coding language is a key aspect of learning to code and learning a particular coding language
listOfProducts = []
valueIndexes = list.of(0).length(attribute.length)
while true
// initialize product
product = {'name': productName, 'attributes': []}
// add all attributes based on current value indexes
for attribute with index in childs
product[attributes][attribute.name] = {'Attribute': attribute.name, 'value' : attribute[valueIndexes[index]]}
// add product to list
listOfProducts.add(product)
// update current indexes
var i = 0
var finished = false
while true
valueIndexes[i] = 1
// if we have no more values at this depth left, increase depth
if (valueIndexes[i] >= attributes[i].length)
valueIndexes[i] = 0
i
// if we we have no farther to go we are done
if (i > valueIndexes.length)
finished = true
break
else
break
// break if we are done
if finished
break