Loop over objects inside a list and return unique values
Make two sets instead, one for the option
s found so far, and one for the type
s found so far:
const obj = {
"products": [{
"id": 1,
"tags": {
"option": ["A", "B"]
}
}, {
"id": 2,
"tags": {
"option": ["B"],
"type": ["A", "B", "C"]
}
}, {
"id": 3,
"tags": {
"type": ["A"]
}
}, {
"id": 4,
"tags": {
"option": ["B", "C"],
"type": ["A", "C"]
}
}]
};
const options = new Set();
const types = new Set();
for (const { tags: { option=[], type=[] } } of obj.products) {
for (const o of option) options.add(o);
for (const t of type) types.add(t);
}
console.log({
option: [...options],
type: [...types]
});
An alternative, for arbitrary keys:
const obj = {
"products": [{
"id": 1,
"tags": {
"option": ["A", "B"]
}
}, {
"id": 2,
"tags": {
"option": ["B"],
"type": ["A", "B", "C"]
}
}, {
"id": 3,
"tags": {
"type": ["A"]
}
}, {
"id": 4,
"tags": {
"option": ["B", "C"],
"type": ["A", "C"]
}
}]
};
const setObj = {};
for (const { tags } of obj.products) {
for (const [key, arr] of Object.entries(tags)) {
if (!setObj[key]) setObj[key] = new Set();
for (const item of arr) setObj[key].add(item);
}
}
const output = Object.fromEntries(
Object.entries(setObj).map(([key, set]) => [key, [...set]])
);
console.log(output);
You could take a Map
for wanted keys and collect the values in a Set
.
function getUnique(array, keys) {
var maps = new Map(keys.map(k => [k, new Set]));
array.forEach(({ tags }) =>
keys.forEach(k => (tags[k] || []).forEach(v => maps.get(k).add(v))));
return Array.from(maps, ([k, s]) => ({ [k]: Array.from(s) }));
}
var data = { products: [{ id: 1, tags: { option: ["A", "B"] } }, { id: 2, tags: { option: ["B"], type: ["A", "B", "C"] } }, { id: 3, tags: { type: ["A"] } }, { id: 4, tags: { option: ["B", "C"], type: ["A", "C"] } }] },
unique = getUnique(data.products, ['option', 'type']);
console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can create an object with two required keys and then set then to empty arrays. Then loop through the array and add the new elements to that array and after that remove the duplicates
const arr = [{
"id": 1,
"tags": {
"option": ["A", "B"]
}}, {
"id": 2,
"tags": {
"option": ["B"],
"type": ["A", "B", "C"]
} }, {
"id": 3,
"tags": {
"type": ["A"]
}}, {
"id": 4,
"tags": {
"option": ["B", "C"],
"type": ["A", "C"]
}}]
const object = {option:[] , type: []}
arr.forEach(({tags}) => {
for(let prop in object){
if(tags[prop]){
object[prop] = [...new Set([...object[prop], ...tags[prop]])]
}
}
})
console.log(object)