I'm trying to use Lodash to grab unique values from an array of objects, then use those values as keys to sort the array of objects into. I was able to reach a solution, however I'm not sure it's the most sophisticated, readable or performance efficient way of doing this.
Using _.uniq
and _.map
, I was able to get the unique country
values from each artist
. I then looped through those values and filtered artists
by them.
let artists = [
{ name: "Bob Jones", country: "Australia"},
{ name: "Jane Smith", country: "Australia"},
{ name: "James Good", country: "USA"},
{ name: "Jeremy Bond", country: "Japan"},
]
let countries = _.uniq(_.map(artists, 'country'))
// ["Australia", "USA", "Japan"]
let res = []
for (let i = 0; i < countries.length; i++) {
let country = countries[i]
let obj = {
country: country,
artists: artists.filter(artist => artist.country === country)
}
res.push(obj)
}
console.log(res)
/* [
{ country: "Australia",
artists: [
{ name: "Bob Jones", country: "Australia"},
{ name: "Jane Smith", country: "Australia"}
]
},
{ country: "USA",
artists: [
{ name: "James Good", country: "USA"}
]
},
{ country: "Japan",
artists: [
{ name: "Jeremy Bond", country: "Japan"}
]
}
]
*/
Is there any Lodash feature I can use in place of the for loop and object assigning?
Use _.groupBy()
to collect the artists to an object of { [country]: artists }
, and then use _.map()
to transform the object to an array:
const artists = [
{ name: "Bob Jones", country: "Australia"},
{ name: "Jane Smith", country: "Australia"},
{ name: "James Good", country: "USA"},
{ name: "Jeremy Bond", country: "Japan"},
]
const result = _.map(
_.groupBy(artists, 'country'),
(artists, country) => ({ country, artists })
)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
And the same solution with lodash/fp - using _.flow()
to generate a function:
const { flow, groupBy, map, head } = _
const byCountry = flow(
groupBy('country'),
map(artists => ({ country: head(artists).country, artists }))
)
const artists = [
{ name: "Bob Jones", country: "Australia"},
{ name: "Jane Smith", country: "Australia"},
{ name: "James Good", country: "USA"},
{ name: "Jeremy Bond", country: "Japan"},
]
const result = byCountry(artists)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>