0

From my server rest API, I request a javascript object that has the following structure:

[
  {
    "msgID": 3,
    "admTag": {
      "tagName": "Employee"
    }
  },
  {
    "msgID": 3,
    "admTag": {
      "tagName": "Safety"
    }
  },
  {
    "msgID": 3,
    "admTag": {
      "tagName": "Performance"
    }
  },
  {
    "msgID": 7,
    "admTag": {
      "tagName": "Role Based Training"
    }
  },
  {
    "msgID": 7,
    "admTag": {
      "tagName": "Account Service Information"
    }
  },
  {
    "msgID": 6,
    "admTag": {
      "tagName": "Consumer Product Safety Improvement"
    }
  }
]

To use this object on the client, I need to transform the structure to group by the msgID property and assign to it an array containing the values of the associated tagName. Like so:

[{
    "3": ["Employee","Safety","Performance"],
    "7": ["Role Based Training","Account Service Information"],
    "6": ["Consumer Product Safety Improvement"]
}]

I can accomplish this using a nested for loop but I know it can be done more efficiently and with less code using underscore. Using groupBy I am able to get a grouping of the msgID's which gives me the keys I need:

_.groupBy(tags.tags, function(model){ 
  return model.msgID;
});

...but I'm unsure how to 'pluck' the tagNames from the resulting object and assign them to the proper msgID.

Greatly appreciate any help on this!

3 Answers 3

1

A solution in plain Javascript. Just four lines of code.

var array = [{ "msgID": 3, "admTag": { "tagName": "Employee" } }, { "msgID": 3, "admTag": { "tagName": "Safety" } }, { "msgID": 3, "admTag": { "tagName": "Performance" } }, { "msgID": 7, "admTag": { "tagName": "Role Based Training" } }, { "msgID": 7, "admTag": { "tagName": "Account Service Information" } }, { "msgID": 6, "admTag": { "tagName": "Consumer Product Safety Improvement" } }],
    result = {};

array.forEach(function (a) {
    result[a.msgID] = result[a.msgID] || [];
    result[a.msgID].push(a.admTag.tagName);
});

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

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

Comments

0

Using .groupBy, .mapValues and _.map you could do something like this:

var output = _(input)
  .groupBy('msgID')                         // Group by msgId
  .mapValues(function(group) {              // Transform value of each group
    return _.map(group, 'admTag.tagName');  // Return array of tagNames
  })
  .value();

jsFiddle

Comments

0

Using _.reduce from underscore

var result = _.reduce(tags.tags, function(l, r) {
    if (typeof l[r.msgID] === "undefined") {
        l[r.msgID] = [];
    }
    l[r.msgID].push(r.admTag.tagName);
    return l;
}, {});

fiddle

The same can be achieved with the native Array.prototype.reduce with nearly the same code

var result = tags.tags.reduce(function(l, r) {
    if (typeof l[r.msgID] === "undefined") {
        l[r.msgID] = [];
    }
    l[r.msgID].push(r.admTag.tagName);
    return l;
}, {});

fiddle

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.