Caso de Uso
O caso de uso é converter uma matriz de objetos em um mapa de hash com base na cadeia ou função fornecida para avaliar e usar como chave no mapa de hash e valor como um objeto em si. Um caso comum de usar isso é converter uma matriz de objetos em um mapa hash de objetos.
Código
A seguir, um pequeno trecho em JavaScript para converter uma matriz de objetos em um mapa de hash, indexado pelo valor do atributo do objeto. Você pode fornecer uma função para avaliar a chave do mapa de hash dinamicamente (tempo de execução). Espero que isso ajude alguém no 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 hashmap
* @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;
};
Você pode encontrar a essência aqui: Converte a matriz de objetos em HashMap .
javascript
arrays
hashmap
Naveen I
fonte
fonte
Respostas:
Isso é bastante trivial relacionado a
Array.prototype.reduce
:Nota:
Array.prototype.reduce()
é o IE9 +, portanto, se você precisar dar suporte a navegadores mais antigos, precisará preenchê-lo novamente.fonte
result = arr.reduce((map, obj) => (map[obj.key] = obj.val, map), {});
Para os fãs de uma linha do ES6: Dresult = new Map(arr.map(obj => [obj.key, obj.val]));
. Mais importante, torna super claro que um mapa está sendo retornado.Array.prototype.reduce
proposta por jmar777.Map
é realmente mais curto, mas é uma coisa diferente. Eu estava mantendo a linha com a intenção original. Lembre-se de que este não é um fórum, você pode querer ler mais sobre a estrutura SO Q / A.{ "foo": {key: 'foo', val: 'bar'}, "hello": {key: 'hello', val: 'world'} }
. Observe que cada elemento original deve ser mantido em sua totalidade . Ou usando dados do Q:{"345": {id:345, name:"kumar"}, ...}
. CORRECÇÃO: Alterar o código para sermap[obj.key] = obj;
Usando o ES6 Map ( muito bem suportado ), você pode tentar o seguinte:
fonte
Map
você precisa usar,result.get(keyName)
em vez de apenasresult[keyName]
. Observe também que qualquer objeto pode ser usado como chave e não apenas como uma string.var result = new Map(arr.map(i => [i.key, i.val] as [string, string]));
que alguns podem achar mais fácil de entender. Nota doas [string, string]
tipo de conversão adicionada.Result is: [["foo","bar"],["hello","world"]]
result
não é um hash, conforme solicitado pelo OP.var result = new Map<string, string>(arr.map(i => [i.key, i.val]));
Com o lodash , isso pode ser feito usando keyBy :
fonte
Usando o spread ES6 + Object.assign:
fonte
const hash = Object.assign({}, ...(<{}>array.map(s => ({[s.key]: s.value}))));
teve que fazer essa alteração para trabalhar com texto datilografado.Usando o operador spread:
Demonstração do snippet de código no jsFiddle .
fonte
Você pode usar Array.prototype.reduce () e o Mapa JavaScript real em vez de apenas um Objeto JavaScript .
O que é diferente entre Mapa e Objeto?
Antes, antes de o Map ser implementado no JavaScript, o Object era usado como um mapa por causa de sua estrutura semelhante.
Dependendo do seu caso de uso, se você precisar ter chaves solicitadas, precisar acessar o tamanho do mapa ou ter a adição e remoção frequentes do mapa, é preferível um Mapa.
Citação do documento MDN : Os
objetos são semelhantes aos Mapas, pois ambos permitem definir chaves para valores, recuperar esses valores, excluir chaves e detectar se algo está armazenado em uma chave. Por causa disso (e porque não havia alternativas internas), os Objetos têm sido usados como Mapas historicamente; no entanto, existem diferenças importantes que tornam o uso de um mapa preferível em certos casos:
fonte
(mapAccumulator, obj) {...}
para(mapAccumulator, obj) => {...}
Você pode usar o novo
Object.fromEntries()
método.Exemplo:
fonte
versão es2015:
fonte
Isto é o que estou fazendo no TypeScript. Tenho uma pequena biblioteca de utilitários onde coloco coisas como esta
uso:
ou se você tiver um identificador diferente de 'id'
fonte
Existem maneiras melhores de fazer isso, conforme explicado por outros pôsteres. Mas se eu quero me ater ao JS puro e à moda antiga, aqui está:
fonte
Se você deseja converter para o novo mapa ES6, faça o seguinte:
Por que você deve usar esse tipo de mapa? Bem, isso é com você. Dê uma olhada nisso .
fonte
Usando Javascript simples
fonte
Com
lodash
:fonte
Uma pequena melhoria no
reduce
uso:fonte
experimentar
Mostrar snippet de código
fonte
A seguir, um pequeno trecho que eu criei em javascript para converter a matriz de objetos em mapa de hash, indexada pelo valor do atributo do objeto. Você pode fornecer uma função para avaliar a chave do mapa de hash dinamicamente (tempo de execução).
Você pode encontrar a essência aqui: https://gist.github.com/naveen-ithappu/c7cd5026f6002131c1fa
fonte
Array.prototype
!