Home > Software design >  How to get unique values from an array of JS objects?
How to get unique values from an array of JS objects?

Time:07-21

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

  • Related