3
\$\begingroup\$

I'm transforming this:

[["Apples", "fruitgroup", "123"], ["Bananas", "fruitgroup", "012"], ["Jumbo Jet", "planegroup", "99"], ["Crop duster", "planegroup", "40"], ["Melons", "fruitgroup", "55"]] 

into this:

["Apples or Bananas or Melons [x]", "Jumbo Jet or Crop duster [x]"] 

Because basically I have to group the child arrays by whatever is in their second index, or [1], and then join them with " or ".

I am successful but I'm afraid this isn't really the best way to acheive this. Isn't there a more simple way to do this?

var filters = [["Apples", "fruitgroup", "123"], ["Bananas", "fruitgroup", "012"], ["Jumbo Jet", "planegroup", "99"], ["Crop duster", "planegroup", "40"], ["Melons", "fruitgroup", "55"]], fieldnames = _.uniq(_.map(filters, function (filter) { return filter[1]; })), groups = _.groupBy(filters, function (filter) { return filter[1]; }), strings = _.map(groups, function (group) { return _.map(group, function (item) { return item[0]; }).join(" or ") + " [x]"; }); console.log(strings); 
\$\endgroup\$
2
  • 1
    \$\begingroup\$Honestly, this looks fine - as long as the other people using it are familiar with functional programming. It may not be particularly "elegant" (which to me is sometimes used as a synonym for 'clever') but I think that if your data are consistently formatted in this way then hardcoding the indexes is okay as long as it is documented.\$\endgroup\$CommentedAug 26, 2015 at 17:39
  • \$\begingroup\$Yes, the data I'm getting is consistently formatted this way. If they were to change the data we would probably get a deprecation notice for a few months... Without getting into too much detail, we are right now trying to see if we should either have the client modify the data like I have done here, or have the server do it. (It's an enterprise level app product, where there are lots of inter-services) So the server can either send the data as they are getting it, or they can modify it then send it to client, we haven't decided yet, but I wanted to ensure I'm providing a good POC clientside\$\endgroup\$CommentedAug 26, 2015 at 18:21

1 Answer 1

3
\$\begingroup\$

The approach seems just fine to me.

However, I noticed that your fieldnames variable isn't actually used for anything. So that can go.

You can also use some shortcuts in underscore.js:

var groups, strings; groups = _.groupBy(filters, 1); // group by index 1 (no need for a callback) strings = _.map(groups, function (group) { return _.pluck(group, 0).join(" or ") + " [x]"; // pluck index 0 and join }); 

As much as I like functional style, it does get a bit dense, so I've spread it out a tiny bit, rather than have it all as a run-on var declaration. (If it's an enterprise-level app, I imagine maintenance is a high-priority, so better to err on the side of clarity.)

You could also go the opposite way, and inline the _.groupBy, but I wouldn't recommend it. There's no performance gain, only readability pain.

A compromise might be undescore's chaining system:

var strings = _.chain(filters) .groupBy(1) .map(function (group) { return _.pluck(group, 0).join(" or ") + " [x]"; }) .value(); 

But again, there's little need.

\$\endgroup\$
1
  • \$\begingroup\$Thank you very much! I like what you did with groupBy and with pluck. I'm going to adopt the first example, as I dont think it's necessary for a chain at this time.\$\endgroup\$CommentedAug 27, 2015 at 17:14

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.