Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Use Case

Fairly new to Lodash/Underscore. The use case is to convert an array of objects into a hash map where one property is the key and the other property is the value. Common case of using this is converting a "link" object in a hypermedia response into a hash map of links.

Code

Below is the current code I have. toHashMap appears much more readable, but less efficient. toMap seems to have the best efficiency at the expense of readability. jsfiddle

function toHashMap(data, name, value) {
    return _.zipObject(_.pluck(data, name),
                       _.pluck(data, value));
}

function toMap(data, name, value) {
    return _.reduce(data, function(acc, item) {
        acc[item[name]] = item[value];
        return acc;
    }, {});
}

var data = [
    { rel: 'link1', href: 'url1'},
    { rel: 'link2', href: 'url2'},
    { rel: 'link3', href: 'url3'},
    { rel: 'link4', href: 'url4'},
];

console.log(toHashMap(data, 'rel', 'href'));

console.log(toMap(data, 'rel', 'href'));

Question

Is there a more elegant solution - i.e. both readable and efficient? I suspect that lodash might have a function to do this already, but I haven't found anything like this after looking at the API documentation.

share|improve this question

2 Answers 2

up vote 8 down vote accepted

I think you are looking for _.indexBY

_.indexBy(data, 'rel');
share|improve this answer
    
I don't understand why is this the accepted answer since it doesn't give the same result as the exposed functions –  Pau Fracés Feb 17 at 15:53
    
@PauFracés See below for revised solution. –  Pete Mar 13 at 21:14

Revised Solution

As per Pau Fracés comment above, here is the complete solution. The solution given by John Anderson would index all objects by the key. However, this would not create a key-value pair map.

To complete the solution of generating a full hash map, the values must be mapped to the key. Using the transform function, the values can be extracted from the objects and mapped back to the key or in this case rel.

Pseudo Code

  1. Index all objects by the chosen key.
  2. Map all values to the key.

Code

Below is the complete code with logging enabled. For a non-logging version, remove all lines with the tap function.

var data = [{ rel: 'link1', href: 'url1' }, 
            { rel: 'link2', href: 'url2' }, 
            { rel: 'link3', href: 'url3' },
            { rel: 'link4', href: 'url4' }];

function log(value) {
  document.getElementById("output").innerHTML += JSON.stringify(value, null, 2) + "\n"
}

var hashmap = _.chain(data)
  .indexBy('rel')

  .tap(log) // Line used just for logging

  .transform(function(result, value, key) {
    result[key] = value.href;
  })

  .tap(log)
  
  .value();
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<pre id="output"></pre>

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.