I have the following array of object
const skus = [
{
id: 1,
features: ["Slim"],
fields: [
{ label: "Material", value: "Material1" },
{ label: "Type", value: "Type1" }
]
},
{
id: 2,
features: ["Cotton"],
fields: [
{ label: "Material", value: "Material2" },
{ label: "Type", value: "Type2" }
]
},
{
id: 3,
features: ["Slim"],
fields: [
{ label: "Material", value: "Material3" },
{ label: "Type", value: "Type1" }
]
}
]
And i want the expected output to be
const output = [
{ label: "features", value: ["Slim", "Cotton"] },
{ label: "Material", value: ["Material1", "Material2", "Material3"] },
{ label: "Type", value: ["Type1", "Type2"] }
]
I tried the following way
const output = [];
let featureArr = [];
let fieldsArr = []
skus.forEach(e => {
e.features.forEach(f => {
featureArr.push(f);
});
e.fields.forEach(f => {
fieldsArr.push({ label: f.label, value: f.value });
});
});
featureArr = _.uniq(featureArr);
fieldsArr = _.uniqBy(fieldsArr, 'value')
fieldsArr = _.groupBy(fieldsArr, 'label');
output.push({ label: 'Features', value: featureArr })
for (const k in fieldsArr) {
let valArr = []
valArr = fieldsArr[k].map(v => v.value)
output.push({ label: k, value: valArr });
}
I'm getting the expected output, but here multiple loops are present. Is there a way on how can i write the solution in more optimized way.
First Build an object with values as Sets
. Then convert the object of sets into array of array.
const skus = [
{
id: 1,
features: ["Slim"],
fields: [
{ label: "Material", value: "Material1" },
{ label: "Type", value: "Type1" }
]
},
{
id: 2,
features: ["Cotton"],
fields: [
{ label: "Material", value: "Material2" },
{ label: "Type", value: "Type2" }
]
},
{
id: 3,
features: ["Slim"],
fields: [
{ label: "Material", value: "Material3" },
{ label: "Type", value: "Type1" }
]
}
];
const update = data => {
const res = {};
data.forEach(item => {
const features = res["features"] || new Set();
item.features.forEach(fea => features.add(fea));
res["features"] = features;
item.fields.forEach(field => {
const labels = res[field.label] || new Set();
labels.add(field.value);
res[field.label] = labels;
});
});
return Object.keys(res).map(key => ({ label: key, value: [...res[key]] }));
};
console.log(update(skus));