Cas d'utilisation
Le cas d'utilisation consiste à convertir un tableau d'objets en une carte de hachage basée sur une chaîne ou une fonction fournie pour évaluation et à utiliser comme clé dans hashmap et la valeur en tant qu'objet lui-même. Le cas courant d'utilisation de ceci est la conversion d'un tableau d'objets en une carte de hachage d'objets.
Code
Voici un petit extrait de code javascript permettant de convertir un tableau d'objets en hash map, indexés par la valeur d'attribut de l'objet. Vous pouvez fournir une fonction pour évaluer la clé de la carte de hachage de manière dynamique (exécution). J'espère que cela aidera tout le monde à l'avenir.
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;
};
Vous pouvez trouver le résumé ici: https://Gist.github.com/naveen-ithappu/c7cd5026f6002131c1fa
C’est assez simple à faire avec 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' }
_
Remarque: Array.prototype.reduce()
est IE9 +. Par conséquent, si vous devez prendre en charge des navigateurs plus anciens, vous devrez le polyfiller.
En utilisant ES6 Map ( assez bien supporté ), vous pouvez essayer ceci:
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])
// Unfortunately maps don't stringify well. This is the contents in array form.
console.log("Result is: " + JSON.stringify([...result]));
// Map {"foo" => "bar", "hello" => "world"}
En utilisant l'opérateur de propagation:
const result = arr.reduce(
(accumulator, target) => ({ ...accumulator, [target.key]: target.val }),
{});
Démonstration de l'extrait de code sur jsFiddle .
Utilisation de ES6 spread + Object.assign:
array = [{key: 'a', value: 'b', redundant: 'aaa'}, {key: 'x', value: 'y', redundant: 'zzz'}]
const hash = Object.assign({}, ...array.map(s => ({[s.key]: s.value})));
console.log(hash) // {a: b, x: y}
Vous pouvez utiliser Array.prototype.reduce () et le code JavaScript actuel Map au lieu de JavaScript uniquement. Objet .
let keyValueObjArray = [
{ key: 'key1', val: 'val1' },
{ key: 'key2', val: 'val2' },
{ key: 'key3', val: 'val3' }
];
let keyValueMap = keyValueObjArray.reduce((mapAccumulator, obj) => {
// either one of the following syntax works
// mapAccumulator[obj.key] = obj.val;
mapAccumulator.set(obj.key, obj.val);
return mapAccumulator;
}, new Map());
console.log(keyValueMap);
console.log(keyValueMap.size);
Quelle est la différence entre Map And Object?
Auparavant, avant que Map ne soit implémenté en JavaScript, Object était utilisé en tant que Map en raison de sa structure similaire.
En fonction de votre cas d'utilisation, si vous devez avoir besoin de clés commandées, si vous devez accéder à la taille de la carte ou si des ajouts et des retraits sont fréquents, une carte est préférable.
Citation de document MDN :
Les objets sont similaires aux cartes en ce qu’ils vous permettent de définir des valeurs pour les clés, de récupérer ces valeurs, de supprimer des clés et de détecter si un élément est stocké dans une clé. Pour cette raison (et parce qu'il n'y avait pas d'alternative intégrée), les objets ont été utilisés historiquement comme cartes; Cependant, il existe des différences importantes qui rendent l'utilisation d'une carte préférable dans certains cas:
version es2015:
const myMap = new Map(objArray.map(obj => [ obj.key, obj.val ]));
C'est ce que je fais dans TypeScript. J'ai une petite bibliothèque utils dans laquelle je mets des choses comme celle-ci.
export const arrayToHash = (array: any[], id: string = 'id') =>
array.reduce((obj, item) => (obj[item[id]] = item , obj), {})
usage:
const hash = arrayToHash([{id:1,data:'data'},{id:2,data:'data'}])
ou si vous avez un identifiant autre que 'id'
const hash = arrayToHash([{key:1,data:'data'},{key:2,data:'data'}], 'key')
Utiliser du Javascript simple
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
Il existe de meilleures façons de le faire, comme l'expliquent d'autres affiches. Mais si je veux rester fidèle à JS et à l’ancienne façon de le faire, la voici:
var arr = [
{ key: 'foo', val: 'bar' },
{ key: 'hello', val: 'world' },
{ key: 'hello', val: 'universe' }
];
var map = {};
for (var i = 0; i < arr.length; i++) {
var key = arr[i].key;
var value = arr[i].val;
if (key in map) {
map[key].Push(value);
} else {
map[key] = [value];
}
}
console.log(map);
essayer
let toHashMap = (a,f) => a.reduce((a,c)=> (a[f(c)]=c,a),{});
let arr=[
{id:123, name:'naveen'},
{id:345, name:"kumar"}
];
let fkey = o => o.id; // function changing object to string (key)
let toHashMap = (a,f) => a.reduce((a,c)=> (a[f(c)]=c,a),{});
console.log( toHashMap(arr,fkey) );
// Adding to prototype is NOT recommented:
//
// Array.prototype.toHashMap = function(f) { return toHashMap(this,f) };
// console.log( arr.toHashMap(fkey) );
Vous pouvez utiliser la nouvelle méthode Object.fromEntries ()
const array = [
{key: 'a', value: 'b', redundant: 'aaa'},
{key: 'x', value: 'y', redundant: 'zzz'}
]
const hash = Object.fromEntries(
array.map(e => [e.key, e.value])
)
console.log(hash) // {a: b, x: y}
Une petite amélioration sur l'utilisation de reduce
:
var arr = [
{ key: 'foo', val: 'bar' },
{ key: 'hello', val: 'world' }
];
var result = arr.reduce((map, obj) => ({
...map,
[obj.key] = obj.val
}), {});
console.log(result);
// { foo: 'bar', hello: 'world' }
Voici un petit extrait que j'ai créé en javascript pour convertir un tableau d'objets en hash map, indexé par la valeur d'attribut de l'objet. Vous pouvez fournir une fonction pour évaluer la clé de la carte de hachage de manière dynamique (exécution).
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;
};
Vous pouvez trouver le résumé ici: https://Gist.github.com/naveen-ithappu/c7cd5026f6002131c1fa