I have the following two arrays of objects that I want to merge in one array but based on some nested keys and values inside the nested object of the first array.
Here's what I have right now:
const variants = [{
"name": "Name 1",
"variationValues": {
"P00003": "mappedValue1",
"P00004": "mappedValue4",
}
}, {
"name": "Name 2",
"variationValues": {
"P00003": "mappedValue2"
}
}, {
"name": "Name 3",
"variationValues": {
"P00003": "mappedValue3"
}
}]
const variationAttributes = [{
"id": "P00003",
"name": "Variant Name",
"attributes": [{
"name": "Variant Name 1",
"description": "Variant Description 1",
"attribute": "mappedValue1"
}, {
"name": "Variant Name 2",
"description": "Variant Description 2",
"attribute": "mappedValue2"
}, {
"name": "Variant Name 3",
"description": "Variant Description 3",
"attribute": "mappedValue3"
}, {
"name": "Variant Name 4",
"description": "Variant Description 4",
"attribute": "mappedValue4"
}]
}, {
"id": "P00004",
"name": "Variant Name",
"attributes": [{
"name": "Variant Name 4",
"description": "Variant Description 4",
"attribute": "mappedValue4"
}]
}]
And here is the expected result:
const result = [{
"variants": [{
"name": "Name 1",
"variationValues": {
"P00003": {
"name": "Variant Name 1",
"description": "Variant Description 1",
"attribute": "mappedValue1"
},
"P00004": {
"name": "Variant Name 4",
"description": "Variant Description 4",
"attribute": "mappedValue4"
}
}
}, {
"name": "Name 2",
"variationValues": {
"P00003": {
"name": "Variant Name 2",
"description": "Variant Description 2",
"attribute": "mappedValue2"
}
}
}, {
"name": "Name 3",
"variationValues": {
"P00003": {
"name": "Variant Name 3",
"description": "Variant Description 3",
"attribute": "mappedValue3"
}
}
}]
}]
Basically it should come down to the following:
variants.variationValues['P00003']
to map to variationAttributes.id
variants.variationValues[value]
to map to variationAttributes.attribute.attribute[value]
I have tried to start using map and reduce methods, but I'm not even sure what's the best place to start.
Any advice will be greatly appreciated, thanks in advance!
The following code combines the two arrays like you specified:
// Data
const variants = [{"name":"Name 1","variationValues":{"P00003":"mappedValue1"}},{"name":"Name 2","variationValues":{"P00003":"mappedValue2"}},{"name":"Name 3","variationValues":{"P00003":"mappedValue3"}}];
const variationAttributes = [{"id":"P00003","name":"Variant Name","attributes":[{"name":"Variant Name 1","description":"Variant Description 1","attribute":"mappedValue1"},{"name":"Variant Name 2","description":"Variant Description 2","attribute":"mappedValue2"},{"name":"Variant Name 3","description":"Variant Description 3","attribute":"mappedValue3"}]}];
// Solution code
console.log( getMappedVariants() );
function getMappedVariants() {
return variants.map((variant) => ({
...variant,
variationValues: mapValuesToAttributes(variant.variationValues),
}));
}
function mapValuesToAttributes(values) {
const attributes = {};
for (const id in values) attributes[id] = findAttribute(id, values[id]);
return attributes;
}
function findAttribute(id, value) {
const variation = variationAttributes.find((v) => v.id === id);
const attribute = variation.attributes.find((a) => a.attribute === value);
return attribute;
}
For the sport of it this could be reduced to one single function, but I would argue that this is the highest level of compression that is still readable.
Just for the sake of it though, here is the abomination of a single function that has the same result:
const variants = [{"name":"Name 1","variationValues":{"P00003":"mappedValue1"}},{"name":"Name 2","variationValues":{"P00003":"mappedValue2"}},{"name":"Name 3","variationValues":{"P00003":"mappedValue3"}}];
const variationAttributes = [{"id":"P00003","name":"Variant Name","attributes":[{"name":"Variant Name 1","description":"Variant Description 1","attribute":"mappedValue1"},{"name":"Variant Name 2","description":"Variant Description 2","attribute":"mappedValue2"},{"name":"Variant Name 3","description":"Variant Description 3","attribute":"mappedValue3"}]}];
const getMappedVariants = () =>
variants.map((variant) => ({
...variant,
variationValues: Object.fromEntries(
Object.entries(variant.variationValues).map(([id, value]) => [
id,
variationAttributes
.find((v) => v.id === id)
?.attributes?.find?.((a) => a.attribute === value),
])
),
}));
console.log(getMappedVariants());