HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Transforming an array of arrays into an array with joins

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arraysarrayintotransformingwithjoins

Problem

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

Solution

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.

Code Snippets

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

Context

StackExchange Code Review Q#101991, answer score: 3

Revisions (0)

No revisions yet.