I have a given array of objects something like:
var items = [
{item: [{foo: 21, bar: 'a' }, {foo: 5,bar: 'e'},{foo: 167, bar: 'c'}]},
{item: [{foo: 42, bar: 'a' }, {foo: 45,bar: 'd'},{foo: 7, bar: 'c'}]},
{item: [{foo: 99, bar: 'b' }, {foo: 35,bar: 'c'},{foo: 22, bar: 'e'}]},
{item: [{foo: 31, bar: 'e' }, {foo: 22,bar: 'd'},{foo: 12, bar: 'a'}]}
]
and I would like to get a new array that returns the unique values of all the bar values, so it would look something like:
var uniqueBars = ['a','b','c','d','e'];
I have a solution for this by looping through all of the items, but I'm guessing there is a more efficient way to do this using ES6 features.
Is there a way to create the uniqueBars array above using ES6 features?
Iterate over items with flatMap and for each inner array map over those objects to return each bar value. Shove the resulting sorted flat array into a Set to remove the duplicates and then spread that back out into an array so you can log the deduped values.
const items=[{item:[{foo:21,bar:"a"},{foo:5,bar:"e"},{foo:167,bar:"c"}]},{item:[{foo:42,bar:"a"},{foo:45,bar:"d"},{foo:7,bar:"c"}]},{item:[{foo:99,bar:"b"},{foo:35,bar:"c"},{foo:22,bar:"e"}]},{item:[{foo:31,bar:"e"},{foo:22,bar:"d"},{foo:12,bar:"a"}]}];
// For each `obj.item.map` you'll get a nested array of
// bar values from each object. Use `flatMap` on that array
// to get all the values into one array, and then sort it
const flattened = items.flatMap(obj => {
return obj.item.map(inner => inner.bar);
}).sort();
// Pass the flattened array into a new Set
// and use spread to work that set into a new array
const deduped = [...new Set(flattened)];
console.log(deduped);
Here a one-liner (not sure it's the best way though) :
[...new Set(items.map(obj => obj.item.map(o => o.bar)).flat())]
As suggested by @Mulan and @Andy, instead of [].map().flat(), prefer flatMap():
[...new Set(items.flatMap(obj => obj.item.map(o => o.bar)))]
You could supply a path of keys and get the values for a Set.
const
getValues = (data, [key, ...keys]) => data.flatMap(o => keys.length
? getValues(o[key], keys)
: o[key]
),
items = [{ item: [{ foo: 21, bar: 'a' }, { foo: 5, bar: 'e' }, { foo: 167, bar: 'c' }] }, { item: [{ foo: 42, bar: 'a' }, { foo: 45, bar: 'd' }, { foo: 7, bar: 'c' }] }, { item: [{ foo: 99, bar: 'b' }, { foo: 35, bar: 'c' }, { foo: 22, bar: 'e' }] }, { item: [{ foo: 31, bar: 'e' }, { foo: 22, bar: 'd' }, { foo: 12, bar: 'a' }] }],
keys = ['item', 'bar'],
unique = [...new Set(getValues(items, keys))];
console.log(...unique);