I need some help figuring out how to get unique values from an array of objects in this format. I have reviewed several examples but none had the values of a key being an array. Thanks in advance for your advice.
I have a JS array with complex objects with some object values being arrays:
let array = [
{ key1: ["one","two","four"], key2: [1,2,4] },
{ key1: ["two","four","six"], key2: [2,4,6] },
{ key1: "nine", key2: 9 },
];
I want to get the unique values for all keys in the object (so it will support any structure) and output like this:
[
{
key1: ["one","two","four", "six", "nine"],
key2: [1,2,4,6,9]
}
]
CodePudding user response:
You can try this :
let array = [
{ key1: ["one","two","four"], key2: [1,2,4] },
{ key1: ["two","four","six"], key2: [2,4,6] },
{ key1: "nine", key2: 9 },
];
let keys = [...new Set(array.flatMap(d => Object.keys(d)))];
let valuesAsObj = Object.fromEntries(
keys.map(k => [
k,
[... new Set(array.flatMap(d => d[k] ? d[k] : null).filter(v => v != null && v != undefined))]
])
);
let valuesAsArr = keys.map(k => [... new Set(array.flatMap(d => d[k] ? d[k] : null).filter(v => v != null && v != undefined))])
console.log(valuesAsObj);
console.log(valuesAsArr);
CodePudding user response:
I approached it by creating a Set
for each unique property and adding all the properties to that set.
let array = [
{ key1: ["one","two","four"], key2: [1,2,4] },
{ key1: ["two","four","six"], key2: [2,4,6] },
{ key1: "nine", key2: 9 },
];
const result = {};
array.forEach(a => {
for (let key in a) {
if (!result[key]) result[key] = new Set();
let v = a[key];
if (!Array.isArray(v)) v = [v];
v.forEach(result[key].add, result[key]);
}
});
console.log(result );
const overlyComplicatedResult = Object.entries(result).map(([key,val]) => ({[key]: [...val]}));
console.log(overlyComplicatedResult);
I'm personally happy with the results in the intermediate format that they are stored in the result
variable, which is just a single object where each property is one of the keys and the value of each property is a Set
of all the distinct values.
But, if you really want to transform that into your overly complicated result, where you have an array of objects, each with a single property, and the unique items are stored in an array instead of a Set
, then the code is provided above as a final transformation step using Object.entries
.
CodePudding user response:
You could try something like this:
let array = [
{ key1: ["one","two","four"], key2: [1,2,4] },
{ key1: ["two","four","six"], key2: [2,4,6] },
{ key1: "nine", key2: 9 },
];
let obj = {};
array.forEach((item) =>
Object.entries(item).forEach((entry) => {
if (!obj[entry[0]]) obj[entry[0]] = [];
!Array.isArray(entry[1])
? obj[entry[0]].push(entry[1])
: (obj[entry[0]] = [...obj[entry[0]], ...entry[1]]);
})
);
/*ADDED LOGIC TO HAVE UNIQUE VALUES IN THE OBJECT*/
Object.entries(obj).forEach(
(entry) => (obj[entry[0]] = Array.from(new Set(entry[1])))
);
console.log(obj);
let result = [];
Object.entries(obj).forEach((entry) =>
result.push({
[entry[0]]: Array.from(new Set(entry[1])),
})
);
console.log(result);