2014-10-08 8 views
79

Use CaseConvertire matrice oggetto hash mappa, indicizzata da un valore di attributo di oggetto

Il caso d'uso è di convertire un array di oggetti in una mappa hash basato sulla stringa o funzione fornita per valutare e uso come chiave in hashmap e valore come oggetto stesso. Caso comune di utilizzo di questo è la conversione di una matrice di oggetti in una mappa hash di oggetti.

codice

seguito è piccolo frammento in javascript per convertire matrice di oggetti a hash mappa, indicizzato dal valore dell'attributo dell'oggetto. È possibile fornire una funzione per valutare la chiave della mappa hash in modo dinamico (tempo di esecuzione). Spero che questo aiuti qualcuno in futuro.

function isFunction(func){ 
    return Object.prototype.toString.call(func) === '[object Function]'; 
} 

/** 
* This function converts an array to hash map 
* @param {String | function} key describes the key to be evaluated in each object to use as key for hasmap 
* @returns Object 
* @Example 
*  [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap("id") 
     Returns :- Object {123: Object, 345: Object} 

     [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap(function(obj){return obj.id+1}) 
     Returns :- Object {124: Object, 346: Object} 
*/ 
Array.prototype.toHashMap = function(key){ 
    var _hashMap = {}, getKey = isFunction(key)?key: function(_obj){return _obj[key];}; 
    this.forEach(function (obj){ 
     _hashMap[getKey(obj)] = obj; 
    }); 
    return _hashMap; 
}; 

Potete trovare il senso qui: https://gist.github.com/naveen-ithappu/c7cd5026f6002131c1fa

+0

È necessario includere qualsiasi codice pertinente nella domanda stessa. – jmar777

+1

Qual è la domanda qui? –

risposta

-1

seguito è piccolo frammento ho creato in javascript per convertire array di oggetti di hash mappa, indicizzato da valore dell'attributo di oggetto. È possibile fornire una funzione per valutare la chiave della mappa hash in modo dinamico (tempo di esecuzione).

function isFunction(func){ 
    return Object.prototype.toString.call(func) === '[object Function]'; 
} 

/** 
* This function converts an array to hash map 
* @param {String | function} key describes the key to be evaluated in each object to use as key for hasmap 
* @returns Object 
* @Example 
*  [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap("id") 
     Returns :- Object {123: Object, 345: Object} 

     [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap(function(obj){return obj.id+1}) 
     Returns :- Object {124: Object, 346: Object} 
*/ 
Array.prototype.toHashMap = function(key){ 
    var _hashMap = {}, getKey = isFunction(key)?key: function(_obj){return _obj[key];}; 
    this.forEach(function (obj){ 
     _hashMap[getKey(obj)] = obj; 
    }); 
    return _hashMap; 
}; 

Potete trovare il senso qui: https://gist.github.com/naveen-ithappu/c7cd5026f6002131c1fa

+5

Per favore, per favore, non raccomandare di estendere 'Array.prototype'! – jmar777

+0

@Naveen I Spostare questo codice alla domanda – hindmost

+0

Ah, capisco. Inizialmente pensavo che questa fosse una risposta proposta :) – jmar777

178

Questo è abbastanza banale a che fare con Array.prototype.reduce:

var arr = [ 
    { key: 'foo', val: 'bar' }, 
    { key: 'hello', val: 'world' } 
]; 

var result = arr.reduce(function(map, obj) { 
    map[obj.key] = obj.val; 
    return map; 
}, {}); 

console.log(result); 
// { foo: 'bar', hello: 'world' } 

Nota:Array.prototype.reduce() è IE9 +, quindi se avete bisogno di supportare più vecchio i browser dovrai riempirlo di polyfill.

+0

Modificato l'usecase per evitare confusione. Ho cercato di indirizzare lo scenario che è più spesso incontrato dagli sviluppatori JS nell'applicazione view driven. –

+0

Esattamente la risposta che stavo cercando. – emil

+2

'result = arr.reduce ((map, obj) => (map [obj.key] = obj.val, map), {}); ' Per i fan one-liner ES6: D – Mtz

104

Utilizzando ES6 Map (pretty well supported), si può provare questo:

var arr = [ 
    { key: 'foo', val: 'bar' }, 
    { key: 'hello', val: 'world' } 
]; 

var result = new Map(arr.map((i) => [i.key, i.val])); 

// When using TypeScript, need to specify type: 
// var result = arr.map((i): [string, string] => [i.key, i.val]) 

console.log(result); 
// Map {"foo" => "bar", "hello" => "world"} 
+5

Perfetto !!!!!!!! – Cody

+3

funziona, ma per qualche motivo, il compilatore del dattiloscritto non è contento di questa affermazione – Blauhirn

+4

@Blauhirn Typescript e le sue tipizzazioni. Prova invece a usare questa riga: 'var result = arr.map ((i): [string, string] => [i.key, i.val])'. Perché 'Map' accetta le voci'? [string, string] [] 'dobbiamo digitare esplicitamente il risultato del metodo passato in' map() 'come coppia di stringhe. Spero che funzioni per te! – mateuscb

13

Con lodash, questo può essere fatto utilizzando keyBy:

var arr = [ 
    { key: 'foo', val: 'bar' }, 
    { key: 'hello', val: 'world' } 
]; 

var result = _.keyBy(arr, o => o.key); 

console.log(result); 
// Object {foo: Object, hello: Object} 
0

Utilizzando semplice Javascript

var createMapFromList = function(objectList, property) { 
    var objMap = {}; 
    objectList.forEach(function(obj) { 
     objMap[obj[property]] = obj; 
    }); 
    return objMap; 
    }; 
// objectList - the array ; property - property as the key 
+2

non sta utilizzando .map (...) inutile in questo esempio in quanto non si restituisce nulla in esso? Suggerirei per ogni caso in questo caso. – cuddlecheek

+0

@cuddlecheek è vero in realtà .. grazie –

0

versione es2015:

const myMap = new Map(objArray.map(obj => [ obj.key, obj.val ])); 
0

Utilizzando l'operatore diffusione:

const result = arr.reduce(
    (accumulator, target) => ({ ...accumulator, [target.key]: target.val }), 
    {}); 

Dimostrazione del frammento di codice sul jsFiddle.

Problemi correlati