Anwendungsfall
Der Anwendungsfall besteht darin, ein Array von Objekten in eine Hash-Map zu konvertieren, die auf einer Zeichenfolge oder Funktion basiert, die zur Auswertung und Verwendung als Schlüssel in der Hash-Map und zum Wert als Objekt selbst bereitgestellt wird. Ein häufiger Fall bei dieser Verwendung ist das Konvertieren eines Arrays von Objekten in eine Hash-Map von Objekten.
Code
Das Folgende ist ein kleines Snippet in JavaScript, um ein Array von Objekten in eine Hash-Map zu konvertieren, die durch den Attributwert des Objekts indiziert ist. Sie können eine Funktion bereitstellen, um den Schlüssel der Hash-Map dynamisch auszuwerten (Laufzeit). Hoffe das hilft jemandem in Zukunft.
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;
};
Das Wesentliche finden Sie hier: Konvertiert ein Array von Objekten in HashMap .
quelle
Antworten:
Dies ist ziemlich trivial zu tun mit
Array.prototype.reduce
:Hinweis:
Array.prototype.reduce()
ist IE9 +. Wenn Sie also ältere Browser unterstützen müssen, müssen Sie diese mehrfach ausfüllen.quelle
result = arr.reduce((map, obj) => (map[obj.key] = obj.val, map), {});
Für ES6 Einzeiler-Fans: Dresult = new Map(arr.map(obj => [obj.key, obj.val]));
. Vor allem macht es sehr deutlich, dass eine Karte zurückgegeben wird.Array.prototype.reduce
wie von jmar777 vorgeschlagen.Map
ist zwar kürzer, aber es ist eine andere Sache. Ich hielt mich an die ursprüngliche Absicht. Denken Sie daran, dass dies kein Forum ist. Vielleicht möchten Sie mehr über die SO Q / A-Struktur lesen.{ "foo": {key: 'foo', val: 'bar'}, "hello": {key: 'hello', val: 'world'} }
. Beachten Sie, dass jedes Originalelement in seiner Gesamtheit beibehalten werden sollte . Oder mit den Daten des Q :{"345": {id:345, name:"kumar"}, ...}
. UPDATE: Ändern Sie den Code inmap[obj.key] = obj;
Mit ES6 Map ( ziemlich gut unterstützt ) können Sie Folgendes versuchen:
quelle
Map
Sie verwenden müssen,result.get(keyName)
als nur gegenüberresult[keyName]
. Beachten Sie auch, dass jedes Objekt als Schlüssel und nicht nur als Zeichenfolge verwendet werden kann.var result = new Map(arr.map(i => [i.key, i.val] as [string, string]));
Einige finden sie möglicherweise leichter zu verstehen. Notentypas [string, string]
Besetzung hinzugefügt.Result is: [["foo","bar"],["hello","world"]]
result
ist kein vom OP angeforderter Hash.var result = new Map<string, string>(arr.map(i => [i.key, i.val]));
Mit lodash kann dies mit keyBy erfolgen :
quelle
Verwenden von ES6-Spread + Object.assign:
quelle
const hash = Object.assign({}, ...(<{}>array.map(s => ({[s.key]: s.value}))));
musste diese Änderung vornehmen, um mit Typoskript zu arbeiten.Verwenden des Spread-Operators:
Demonstration des Code-Snippets auf jsFiddle .
quelle
Sie können Array.prototype.reduce () und die tatsächliche JavaScript- Map anstelle eines JavaScript- Objekts verwenden .
Was ist anders zwischen Karte und Objekt?
Zuvor, bevor Map in JavaScript implementiert wurde, wurde Object aufgrund seiner ähnlichen Struktur als Map verwendet.
Abhängig von Ihrem Anwendungsfall ist eine Karte vorzuziehen, wenn Sie Schlüssel bestellt haben müssen, auf die Größe der Karte zugreifen müssen oder häufig Karten hinzufügen und daraus entfernen müssen.
Zitat aus MDN-Dokument :
Objekte ähneln Maps dahingehend, dass Sie beide Schlüssel auf Werte setzen, diese Werte abrufen, Schlüssel löschen und erkennen können, ob etwas an einem Schlüssel gespeichert ist. Aus diesem Grund (und weil es keine integrierten Alternativen gab) wurden Objekte in der Vergangenheit als Karten verwendet. Es gibt jedoch wichtige Unterschiede, die die Verwendung einer Karte in bestimmten Fällen vorzuziehen machen:
quelle
(mapAccumulator, obj) {...}
für(mapAccumulator, obj) => {...}
Sie können die neue
Object.fromEntries()
Methode verwenden.Beispiel:
quelle
es2015 version:
quelle
Dies ist, was ich in TypeScript mache. Ich habe eine kleine Utils-Bibliothek, in der ich solche Dinge platziere
Verwendung:
oder wenn Sie eine andere Kennung als 'id' haben
quelle
Es gibt bessere Möglichkeiten, dies zu tun, wie auf anderen Postern erläutert. Aber wenn ich mich an reine JS und altmodische Art halten will, dann ist es hier:
quelle
Wenn Sie auf die neue ES6- Karte konvertieren möchten, gehen Sie folgendermaßen vor:
Warum sollten Sie diese Art von Karte verwenden? Nun, das liegt an dir. Schauen Sie sich auf diese .
quelle
Mit einfachem Javascript
quelle
Mit
lodash
:quelle
Eine kleine Verbesserung der
reduce
Nutzung:quelle
Versuchen
Code-Snippet anzeigen
quelle
Das Folgende ist ein kleines Snippet, das ich in Javascript erstellt habe, um ein Array von Objekten in eine Hash-Map zu konvertieren, indiziert nach dem Attributwert des Objekts. Sie können eine Funktion bereitstellen, um den Schlüssel der Hash-Map dynamisch auszuwerten (Laufzeit).
Das Wesentliche finden Sie hier: https://gist.github.com/naveen-ithappu/c7cd5026f6002131c1fa
quelle
Array.prototype
!