# Transforming an array of arrays into an array with joins

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

• 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. – theWanderer4865 Aug 26 '15 at 17:39
• 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 – docodemore Aug 26 '15 at 18:21

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.

• 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. – docodemore Aug 27 '15 at 17:14