1

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?

2 Answers 2

4

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);

Sign up to request clarification or add additional context in comments.

6 Comments

This is fantastic! Unfortunately I'm stuck with IE and can't integrate Babel to transform this script (hence why I'm bringing in lodash). Never heard of this ESNext though, I'll check it out
Luckily Babel has an es5 converter! I'll try it out and let you know babeljs.io
EsNext is just another way of saying modern Javascript, I can never remember if a feature came in 2015, 2017 etc. so I just say EsNext. :) This is fantastic! Unfortunately I'm stuck with IE, that's not a problem, any serious JS developer will have some form of build process,. webpack webpack.js.org is a nice one to use if you are not currently doing this.
And this doesn't look like it uses anything particularly modern. It should work in most fairly recent IEs, and even some older ones.
@ScottSauyet Not done much testing here, but this snippet fails on IE11. Most likely because of object shorthand {name,age} and array destructuring [name,age,dept] = v
|
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.