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 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; }
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