I'm looking for an efficient way to return unique values in objects inside an array. For example the next object:
{
"products": [{
"id": 1,
"category": "test1",
"tags": {
"option": ["A", "B"]
}
}, {
"id": 2,
"category": "test2",
"tags": {
"option": ["B"],
"type": ["A", "B", "C"]
}
}, {
"id": 3,
"category": "test1",
"tags": {
"type": ["A"]
}
}, {
"id": 4,
"category": "test2",
"tags": {
"option": ["B", "C"],
"type": ["A", "C"]
}
}]
}
What I want to return is the following:
{"option": [ "A", "B", "C" ] },{"type": ["A", "B", "C"] }
So I want for each item inside the tags object a new object. After that, I want an array with all unique values over all the products.
I do somewhat the same with another function:
Array.from(new Set(data.map(p => { return p.category; })))
This is a level higher which makes it easier. Can someone push me in the right direction?
Make two sets instead, one for the options found so far, and one for the types 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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With