Reputation: 4581
I have the following array of arrays consisting of a name
, age
, and department
[[ "Kevin", 22,"Psychology" ],
[ "Cathy", 26, "Psychology" ],
[ "David", 31, "Engineering" ],
[ "Christine", 23, "Engineering" ]]
I want to create a map based on the unique departments
that would look like this:
{ Psychology: [
{ name: "Cathy", age: 26 },
{ name: "Kevin", age: 22 } ]
},
{ Engineering: [
{ name: "Christine", age: 23 },
{ name: "David", age: 31 } ]
}
The index of department
in the array will always be same. How can this be done utilizing lodash
?
Upvotes: 1
Views: 2267
Reputation: 50797
Here is a lodash solution:
const {flow, groupBy, nth, mapValues, map, zipObject} = _
const transform = flow(
people => groupBy(people, p => nth(p, 2)),
grouped => mapValues(grouped, dept => map(
dept,
person => zipObject(['name', 'age'], person)
))
)
const people = [["Kevin", 22, "Psychology"], ["Cathy", 26, "Psychology"], ["David", 31, "Engineering"], ["Christine", 23, "Engineering"]]
console.log(transform(people))
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
It would probably be made simpler with lodash/fp, but I've never gotten that working correctly. I probably haven't spent much time on it because I'm one of the authors of another FP library for JS, Ramda. The solution above was created by translating my first code, written with Ramda:
const {pipe, groupBy, nth, map, zipObj} = R;
const transform = pipe(
groupBy(nth(2)),
map(map(zipObj(['name', 'age'])))
)
const people = [["Kevin", 22, "Psychology"], ["Cathy", 26, "Psychology"], ["David", 31, "Engineering"], ["Christine", 23, "Engineering"]]
console.log(transform(people))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
I'm guessing that lodash/fp code would probably look pretty similar, except that you'd have to replace the first map
with mapValues
.
Upvotes: 1
Reputation: 24191
Without using a external library, using new ESNext stuff like this is pretty easy.
const data = [
[ "Kevin", 22,"Psychology" ],
[ "Cathy", 26, "Psychology" ],
[ "David", 31, "Engineering" ],
[ "Christine", 23, "Engineering" ]];
const result = data.reduce((a, v) => {
const [name,age,dept] = v;
(a[dept] = a[dept] || []).push({name,age});
return a;
}, {});
console.log(result);
Upvotes: 4