555 Stimmen

Konvertiere das Objekt-Array in eine Hashtabelle, indexiert nach einem Attributwert des Objekts

Anwendungsfall

Der Anwendungsfall besteht darin, ein Array von Objekten in eine Hash-Map umzuwandeln, basierend auf einem String oder einer Funktion, die zur Auswertung und Verwendung als Schlüssel in der Hash-Map und als Wert als Objekt selbst dient. Ein häufiger Anwendungsfall für dies ist die Umwandlung eines Arrays von Objekten in eine Hash-Map von Objekten.

Code

Im Folgenden finden Sie einen kleinen Ausschnitt in JavaScript, um ein Array von Objekten in eine Hash-Map umzuwandeln, indexiert nach dem Attributwert des Objekts. Sie können eine Funktion angeben, um den Schlüssel der Hash-Map dynamisch (zur Laufzeit) zu bewerten.

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

/**
 * Diese Funktion wandelt ein Array in eine Hash-Map um
 * @param {String | function} key beschreibt den Schlüssel, der in jedem Objekt ausgewertet werden soll, um ihn als Schlüssel für die Hash-Map zu verwenden
 * @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;
};

Sie finden das Gist hier: Konvertiert Array von Objekten in HashMap.

33voto

King Friday Punkte 22596

Tersiest

list.reduce((obj, item) => ({...obj, [item.name]: item.value}), {})

const list = [
  { name: 'abc', value: 123 },
  { name: 'xyz', value: 789 },
  { name: 'she', value: 'her' },
  { name: 'he', value: 'him'}
]

console.log(
  list.reduce((obj, item) => ({...obj, [item.name]: item.value}), {})
)

32voto

Pedro Lopes Punkte 2695

Mit dem Spread-Operator:

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

Demonstration des Code-Schnipsels auf jsFiddle.

28voto

Jun711 Punkte 2726

Sie können Array.prototype.reduce() und das tatsächliche JavaScript Map verwenden anstelle von nur einem JavaScript Object.

let keyValueObjArray = [
  { key: 'key1', val: 'val1' },
  { key: 'key2', val: 'val2' },
  { key: 'key3', val: 'val3' }
];

let keyValueMap = keyValueObjArray.reduce((mapAccumulator, obj) => {
  // entweder eine der folgenden Syntaxmöglichkeiten funktioniert
  // mapAccumulator[obj.key] = obj.val;
  mapAccumulator.set(obj.key, obj.val);

  return mapAccumulator;
}, new Map());

console.log(keyValueMap);
console.log(keyValueMap.size);

Was ist der Unterschied zwischen Map und Object?
Früher, bevor Map in JavaScript implementiert wurde, wurde Object als Map verwendet, aufgrund ihrer ähnlichen Struktur.
Je nach Ihrem Anwendungsfall, wenn Sie geordnete Schlüssel benötigen, die Größe der Karte abrufen müssen oder häufige Hinzufügungen und Entfernungen aus der Karte vornehmen müssen, ist eine Map vorzuziehen.

Zitat aus MDN-Dokument:
Objekte sind Maps ähnlich, da beide es ermöglichen, Schlüssel Werte zuzuweisen, diese Werte abzurufen, Schlüssel zu löschen und zu erkennen, ob etwas unter einem Schlüssel gespeichert ist. Deshalb (und weil es keine integrierten Alternativen gab) wurden Objekte historisch als Maps verwendet; es gibt jedoch wichtige Unterschiede, die die Verwendung einer Map in bestimmten Fällen bevorzugenswert machen:

  • Die Schlüssel eines Objekts sind Strings und Symbole, während sie für eine Map jeden Wert haben können, einschließlich Funktionen, Objekten und beliebigen primitiven Werten.
  • Die Schlüssel in einer Map sind geordnet, während hinzugefügte Schlüssel zu einem Objekt dies nicht sind. Daher gibt ein Map-Objekt die Schlüssel in der Reihenfolge der Einfügung zurück, wenn darüber iteriert wird.
  • Sie können die Größe einer Map leicht mit der size-Eigenschaft abrufen, während die Anzahl der Eigenschaften in einem Objekt manuell ermittelt werden muss.
  • Eine Map ist iterierbar und kann daher direkt durchlaufen werden, während das Durchlaufen eines Objekts erfordert, auf irgendeine Weise seine Schlüssel zu erhalten und über sie zu iterieren.
  • Ein Objekt hat einen Prototyp, daher gibt es standardmäßige Schlüssel in der Map, die mit Ihren Schlüsseln kollidieren könnten, wenn Sie nicht vorsichtig sind. Seit ES5 kann dies umgangen werden, indem man map = Object.create(null) verwendet, aber dies wird selten gemacht.
  • Ein Map kann in Szenarien, die häufige Hinzufügungen und Entfernungen von Schlüsselpaaren beinhalten, besser funktionieren.

20voto

baryo Punkte 1441

Es2015 Version:

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

10voto

rhel.user Punkte 1518

Es gibt bessere Wege, dies zu tun, wie es von anderen Beitragenden erklärt wurde. Aber wenn ich mich nur an rein JS und die altmodische Methode halten möchte, dann ist hier:

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);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X