I have an array of objects, where each object has a unique member called id. How do I create a Map where the id if the Map's key?
            Asked
            
        
        
            Active
            
        
            Viewed 1.1k times
        
    6
            
            
        - 
                    Could you explain a bit more, do you have an example array?.. And what output you expect. – Keith Oct 24 '16 at 13:58
- 
                    JSPrefs for the 3 answers below are here: https://jsperf.com/array-to-map-4 – Ross Oct 24 '16 at 15:06
- 
                    Should be pretty simple. Have you tried it yourself? Please show us your code. What did not work? – Bergi Oct 24 '16 at 15:24
3 Answers
8
            
            
        You want to reduce your array into a map:
const arr = [{id:1},{id:2},{id:2}];
const map = arr.reduce((acc, item) => acc.set(item.id, item), new Map());
console.log(map.get(1));Here is a JSPref against using map and forEach. 
In Chrome v53 reduce is fastest, then forEach with map being the slowest.
 
    
    
        Ross
        
- 14,266
- 12
- 60
- 91
- 
                    Curious to know why this got a down vote. It's not making intermediate arrays which may not be faster (and will bump the garbage collector later) – Ross Oct 24 '16 at 14:21
- 
                    
- 
                    I'd say for someone reading the code, this is more literate of its intension. Therefore simpler. Unless you don't know what `reduce` is of course. – Ross Oct 24 '16 at 14:29
- 
                    Harsh downvote. It may look complex on the surface, but this is simply a pure function with no side-effects and so is easier to reason about. – CodingIntrigue Oct 24 '16 at 14:33
- 
                    
- 
                    1@Gothdo I've changed it to `const`. (It appears you didn't get the irony) – Ross Oct 24 '16 at 14:47
- 
                    @Gothdo I've added a JSPref for my own curiosity. For me this runs 48% faster than using `map` – Ross Oct 24 '16 at 14:57
- 
                    
- 
                    Nice. Tbh very little difference on chrome between forEach and reduce on Chrome. It's allocating the arrays rather than called set which is a performance hit. – Ross Oct 24 '16 at 18:56
3
            
            
        You could map a new array in the needed format for the Map.
var array = [{ id: 1, value: 'one' }, { id: 2, value: 'two' }, { id: 3, value: 'three' }, { id: 4, value: 'four' }, { id: 5, value: 'five' }],
    map = new Map(array.map(a => [a.id, a]));
console.log([...map]);.as-console-wrapper { max-height: 100% !important; top: 0; }Or iterate and add the new item to a certain key
var array = [{ id: 1, value: 'one' }, { id: 2, value: 'two' }, { id: 3, value: 'three' }, { id: 4, value: 'four' }, { id: 5, value: 'five' }],
    map = new Map();
array.forEach(a => map.set(a.id, a));
console.log([...map]);.as-console-wrapper { max-height: 100% !important; top: 0; } 
    
    
        Nina Scholz
        
- 376,160
- 25
- 347
- 392
- 
                    1In ES6 it's better to use for..of loop instead of `forEach()` method, see [Are there reasons to use array.forEach() over for…of, when both could be used, in ES6?](http://stackoverflow.com/q/31344516/3853934). `forEach()` is also slower than a loop. – Michał Perłakowski Oct 24 '16 at 14:21
- 
                    
- 
                    But you don't know if someone using this code won't need to modify it to exit the loop. And still it's slower. – Michał Perłakowski Oct 24 '16 at 14:29
- 
                    1@Gothdo Can't see how `for..of` provides any benefits over `forEach` here. In fact, using `forEach` allows for abstraction into a smaller, reusable method, e.g. `const addToMap = item => map.set(item.id, item); array.forEach(addToMap);` – CodingIntrigue Oct 24 '16 at 14:29
- 
                    1@CodingIntrigue If you want to use functional programming with composable methods, you shouldn't use side effects like `set`. So that's hardly an advantage here. At least, use `reduce` instead of `forEach` like in Ross' answer. And really, for imperative iteration (which is what we need here) `for…of` loops are more idiomatic ES6. – Bergi Oct 24 '16 at 15:26
- 
                    @Bergi Not arguing that a pure function isn't a better choice. Just given this answer there is more benefit to forEach. Being idiomatic ES6 is subjective at best. Abstraction is quantifiable, rightly or wrongly used. – CodingIntrigue Oct 24 '16 at 16:40
3
            
            
        You can use Array.prototype.map() to map the array elements to [element.id, element] pairs and then pass the resulting array to the Map constructor.
const arr = [{id: 1, a: true, b: false}, {id: 2, a: false, b: true}]
const map = new Map(arr.map(element => [element.id, element]))
// Check if map looks OK
for (const [key, value] of map) {
  console.log(key, value)
} 
    
    
        Michał Perłakowski
        
- 88,409
- 26
- 156
- 177
