Verschlüsseln Sie Ihre Objekte selbst manuell und verwenden Sie die resultierenden Zeichenketten als Schlüssel für ein normales JavaScript-Wörterbuch. Schließlich sind Sie in der besten Position, um zu wissen, was Ihre Objekte einzigartig macht. Das ist es, was ich tue.
Beispiel:
var key = function(obj){
// Some unique object-dependent key
return obj.totallyUniqueEmployeeIdKey; // Just an example
};
var dict = {};
dict[key(obj1)] = obj1;
dict[key(obj2)] = obj2;
Auf diese Weise können Sie die Indizierung durch JavaScript ohne schweres Heben der Speicherzuweisung und Überlaufbehandlung steuern.
Natürlich, wenn Sie wirklich wollen, dass die "Industrie-grade-Lösung", können Sie eine Klasse parametrisiert durch den Schlüssel-Funktion, und mit allen notwendigen API des Containers, aber wir verwenden JavaScript, und versuchen, einfach und leichtgewichtig zu sein, so dass diese funktionale Lösung ist einfach und schnell.
Die Schlüsselfunktion kann so einfach sein wie die Auswahl der richtigen Attribute des Objekts, z. B. eines Schlüssels oder einer Reihe von Schlüsseln, die bereits eindeutig sind, einer Kombination von Schlüsseln, die zusammen eindeutig sind, oder so komplex wie die Verwendung einiger kryptografischer Hashes wie in DojoX-Kodierung o DojoX UUID . Während die letztgenannten Lösungen eindeutige Schlüssel erzeugen können, versuche ich persönlich, sie um jeden Preis zu vermeiden, vor allem, wenn ich weiß, was meine Objekte einzigartig macht.
Aktualisierung im Jahr 2014: Diese einfache Lösung wurde bereits 2008 beantwortet und bedarf noch immer weiterer Erklärungen. Lassen Sie mich die Idee in Form von Fragen und Antworten erläutern.
Ihre Lösung hat keine echte Raute. Wo ist er?
JavaScript ist eine Hochsprache. Ihre grundlegenden Primitive ( Objekt ) enthält eine Hash-Tabelle zum Speichern von Eigenschaften. Diese Hash-Tabelle wird aus Effizienzgründen normalerweise in einer Low-Level-Sprache geschrieben. Durch die Verwendung eines einfachen Objekts mit String-Schlüsseln nutzen wir eine effizient implementierte Hash-Tabelle ohne jeglichen Aufwand unsererseits.
Woher wissen Sie, dass sie eine Raute verwenden?
Es gibt drei wesentliche Möglichkeiten, eine Sammlung von Objekten über einen Schlüssel adressierbar zu halten:
- Ungeordnet. In diesem Fall müssen wir, um ein Objekt anhand seines Schlüssels zu finden, alle Schlüssel durchgehen und anhalten, wenn wir es gefunden haben. Im Durchschnitt werden n/2 Vergleiche benötigt.
- Bestellt.
- Beispiel 1: ein sortiertes Array - mit einer binären Suche finden wir unseren Schlüssel im Durchschnitt nach ~log2(n) Vergleichen. Viel besser.
- Beispiel #2: ein Baum. Wieder werden es ~log(n) Versuche sein.
- Hash-Tabelle. Im Durchschnitt benötigt sie eine konstante Zeit. Vergleiche: O(n) vs. O(log n) vs. O(1). Aufschwung.
Offensichtlich verwenden JavaScript-Objekte Hash-Tabellen in irgendeiner Form, um allgemeine Fälle zu behandeln.
Verwenden Browser-Anbieter wirklich Hash-Tabellen?
Wirklich.
Können sie Kollisionen bewältigen?
Ja. Siehe oben. Wenn Sie eine Kollision bei ungleichen Zeichenketten gefunden haben, zögern Sie bitte nicht, einen Fehler bei einem Anbieter zu melden.
Was ist also Ihre Idee?
Wenn Sie ein Objekt mit einem Hash versehen wollen, müssen Sie herausfinden, was es einzigartig macht, und es als Schlüssel verwenden. Versuchen Sie nicht, einen echten Hash zu berechnen oder Hash-Tabellen zu emulieren - das zugrundeliegende JavaScript-Objekt erledigt das bereits effizient.
Verwenden Sie diesen Schlüssel mit der JavaScript-Funktion Object
um die eingebaute Hashtabelle zu nutzen und gleichzeitig mögliche Konflikte mit Standardeigenschaften zu vermeiden.
Beispiele für den Anfang:
- Wenn Ihre Objekte einen eindeutigen Benutzernamen enthalten, verwenden Sie diesen als Schlüssel.
- Wenn sie eine eindeutige Kundennummer enthält, verwenden Sie diese als Schlüssel.
- Wenn sie eindeutige, von der Regierung vergebene Nummern enthält, wie US SSNs oder eine Reisepassnummer, und Ihr System lässt keine Duplikate zu - verwenden Sie sie als Schlüssel.
- Wenn eine Kombination von Feldern eindeutig ist, verwenden Sie sie als Schlüssel.
- Die Abkürzung des US-Bundesstaates + Führerscheinnummer ergibt einen hervorragenden Schlüssel.
- Länderkürzel + Passnummer ist auch ein ausgezeichneter Schlüssel.
- Einige Funktionen für Felder oder ein ganzes Objekt können einen eindeutigen Wert zurückgeben - verwenden Sie ihn als Schlüssel.
Ich habe Ihren Vorschlag befolgt und alle Objekte unter Verwendung eines Benutzernamens im Cache gespeichert. Aber ein Schlauberger heißt "toString", was eine eingebaute Eigenschaft ist! Was soll ich jetzt tun?
Wenn es auch nur im Entferntesten möglich ist, dass der resultierende Schlüssel ausschließlich aus lateinischen Buchstaben besteht, sollten Sie natürlich etwas dagegen tun. Fügen Sie zum Beispiel ein beliebiges nicht-lateinisches Unicode-Zeichen am Anfang oder am Ende ein, um einen Konflikt mit den Standardeigenschaften zu vermeiden: "#toString", "#MarySmith". Wenn ein zusammengesetzter Schlüssel verwendet wird, trennen Sie die Schlüsselkomponenten mit einem nicht-lateinischen Trennzeichen: "Name,Stadt,Bundesland".
Im Allgemeinen ist dies der Ort, an dem wir kreativ sein und die einfachsten Schlüssel mit den gegebenen Einschränkungen (Eindeutigkeit, potenzielle Konflikte mit Standardeigenschaften) auswählen müssen.
Hinweis: Eindeutige Schlüssel kollidieren nicht per Definition, während mögliche Hash-Kollisionen von der zugrunde liegenden Object
.
Warum gefallen Ihnen die industriellen Lösungen nicht?
IMHO ist der beste Code überhaupt kein Code: er ist fehlerfrei, erfordert keine Wartung, ist leicht verständlich und wird sofort ausgeführt. Alle "Hashtabellen in JavaScript", die ich gesehen habe, bestanden aus mehr als 100 Zeilen Code und umfassten mehrere Objekte. Vergleichen Sie das mit: dict[key] = value
.
Ein weiterer Punkt: Ist es überhaupt möglich, die Leistung eines in einer Niedrigsprache geschriebenen Urobjekts zu übertreffen, indem man JavaScript und dieselben Urobjekte verwendet, um das zu implementieren, was bereits implementiert ist?
Ich möchte meine Objekte immer noch ohne Schlüssel hashen!
Wir haben Glück: ECMAScript 6 (veröffentlicht im Juni 2015) definiert Karte y einstellen. .
Nach der Definition zu urteilen, können sie die Adresse eines Objekts als Schlüssel verwenden, was Objekte ohne künstliche Schlüssel sofort unterscheidbar macht. OTOH, zwei verschiedene, aber identische Objekte, werden als unterschiedlich abgebildet werden.
Aufschlüsselung des Vergleichs von MDN :
Objekte ähneln Maps insofern, als dass man mit beiden Schlüsseln Werte festlegen kann, diese Werte abrufen, Schlüssel löschen und feststellen, ob etwas unter einem unter einem Schlüssel gespeichert ist. Aus diesem Grund (und weil es keine eingebauten Alternativen gab), wurden Objects in der Vergangenheit als Maps verwendet; allerdings gibt es jedoch wichtige Unterschiede, die die Verwendung einer Map in folgenden Fällen vorteilhafter machen bestimmten Fällen vorzuziehen:
- Die Schlüssel eines Objekts sind Zeichenketten und Symbole, während sie bei einer Karte jeder Wert sein können, einschließlich Funktionen, Objekte und beliebige Primitive.
- Die Schlüssel in Map sind geordnet, während die zum Objekt hinzugefügten Schlüssel nicht geordnet sind. Wenn man also über ein Map-Objekt iteriert, werden die Schlüssel in der Reihenfolge der Einfügung zurück.
- Die Größe einer Karte lässt sich leicht mit der Eigenschaft size ermitteln, während die Anzahl der Eigenschaften eines Objekts manuell bestimmt werden muss.
- Eine Map ist eine Iterable und kann daher direkt iteriert werden, während die Iteration über ein Objekt erfordert, dass man seine Schlüssel auf irgendeine Weise erhält und über sie zu iterieren.
- Ein Objekt hat einen Prototyp, d.h. es gibt Standardschlüssel in der Map, die mit Ihren Schlüsseln kollidieren können, wenn Sie nicht vorsichtig sind. Ab ES5 kann dies map = Object.create(null) umgangen werden, aber das wird nur selten gemacht.
- Eine Map kann in Szenarien, in denen häufig Schlüsselpaare hinzugefügt und entfernt werden, besser funktionieren.