Home > OS >  How to get distinct value from an array of objects containing array
How to get distinct value from an array of objects containing array

Time:12-20

I am trying to get an array of distinct values from the data structure below. I tried using reduce and object keys with no luck. Can somebody please point me in the right direction?

Data:

var data = [{
    "id": 1,
    "Technologies": ["SharePoint", "PowerApps"]
  },
  {
    "id": 2,
    "Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
  },
  {
    "id": 3,
    "Technologies": ["SharePoint"]
  },
  {
    "id": 4,
    "Technologies": ["PowerApps"]
  },
  {
    "id": 5,
    "Technologies": null
  }
]

Finished result should look like:

var distintValues = ["PowerApps", "SharePoint", "SomethingElse", null]

My attempt: https://codepen.io/bkdigital/pen/MWEoLXv?editors=0012

CodePudding user response:

You could use .flatMap() with a Set. .flatMap allows you to map each object's technology to one resulting array, and the Set allows you to remove the duplicates. With the help of optional chaining ?., you can also keep the null value (so it doesn't throw when accessing Technologies) like so:

const data = [{ "id": 1, "Technologies": ["SharePoint", "PowerApps"] }, { "id": 2, "Technologies": ["SharePoint", "PowerApps", "SomethingElse"] }, { "id": 3, "Technologies": ["SharePoint"] }, { "id": 4, "Technologies": ["PowerApps"] }, { "id": 5, "Technologies": null } ];

const res = [...new Set(data.flatMap(obj => obj?.Technologies))];
console.log(res);

CodePudding user response:

[...new Set(
  data
    .map(v => Array.isArray(v.Technologies) ? v.Technologies : [v.Technologies])
    .reduce((t, v) => [...t, ...v], [])
)];

CodePudding user response:

I tried to solve this through JS. Here is my code:

const data = [{
            "id": 1,
            "Technologies": ["SharePoint", "PowerApps"]
        }, {
            "id": 2,
            "Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
        }, {
            "id": 3,
            "Technologies": ["SharePoint"]
        }, {
            "id": 4,
            "Technologies": ["PowerApps"]
        }, {
            "id": 5,
            "Technologies": null
        }]
        const distintValues = [];
        for (let element of data) {
            if (element.Technologies != null) {
                for (let elem of element.Technologies) {
                    if (!distintValues.includes(elem)) {
                        distintValues.push(elem);
                    }
                }
            }
        }
        console.log(distintValues);

CodePudding user response:

In your attempt you tried to do it with reduce so here is how I would do it

var data = [{
    "id": 1,
    "Technologies": ["SharePoint", "PowerApps"]
  },
  {
    "id": 2,
    "Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
  },
  {
    "id": 3,
    "Technologies": ["SharePoint"]
  },
  {
    "id": 4,
    "Technologies": ["PowerApps"]
  },
  {
    "id": 5,
    "Technologies": null
  }
];

const objAsArray = Object.keys(data) // first we get the keys
  .map(key => data[key]) // then we map them to their value

const technologyMap = objAsArray.reduce((acc, data) => {
  // if the entry has technologies we set the key in the accumulation object to true
  if (data.Technologies) {
    data.Technologies.forEach(tech => acc[tech] = true)
  }
  return acc;
}, {})

// at the very end we get the keys of the accumulation object
const uniqueTechnologies =
  Object.keys(
    technologyMap
  )

  • Related