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
)