0
\$\begingroup\$

Trying to write more functional Javascript with the underscore library. Any thoughts on how to improve this to be more functional than imperative? Also, any way to do this without mapObject?

The first of each pair is a "bucket" and the second is a value, I'd like to iterate over the information and get a unique list of what is in each bucket.

var a = [
  ['A',1],
  ['A',1],
  ['A',1],
  ['A',2],
  ['B',1],
  ['B',2],
  ['B',2],
  ['B',4],
  ['C',6],
  ['D',5]
];

//result should be:
//  {
//     A: [1,2],
//     B: [1,2,4],
//     C: [6],
//     D: [5]
//  }

_.chain(a)
 .groupBy(function (pair) {
    var group = pair[0];
    return group;
 })
 .mapObject(function (val, key) {
    var results = _.chain(val)
                   .map(function (pair) {
                     return pair[1]
                   })
                   .uniq()
                   .value();
    return results;
 })
 .value();
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Well you can avoid a few variable assignments by returning immediately, also by using some details of the Underscore.js API, that is by specifying the used indexes for groupBy/map directly.

_.chain(a)
 .groupBy(0)
 .mapObject(function (val, key) {
    return _.chain(val).map(1).uniq().value();
 })
 .value();

I doubt there's a good way to avoid mapObject, after all, that's what it's for.

With 1.7 you could also write that even less verbose:

_.chain(a)
 .groupBy(0)
 .mapObject((val, key) => _.chain(val).map(1).uniq().value())
 .value();

Looks pretty functional to me.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for the tips! I'm forced to use an older version of underscore that didn't have mapObject but I worked around it by chaining map and then object. \$\endgroup\$ Commented Apr 23, 2015 at 17:54

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.