Verwenden einer Ganzzahl als Schlüssel in einem assoziativen Array in JavaScript

101

Wenn ich ein neues JavaScript-Array erstelle und eine Ganzzahl als Schlüssel verwende, wird jedes Element dieses Arrays bis zur Ganzzahl als undefiniert erstellt.

Beispielsweise:

var test = new Array();
test[2300] = 'Some string';
console.log(test);

gibt 2298 undefined's und einen 'Some string' aus.

Wie soll ich JavaScript dazu bringen, 2300 als Zeichenfolge anstelle einer Ganzzahl zu verwenden, oder wie soll ich verhindern, dass 2299 leere Indizes instanziiert werden?

Peter Mortensen
quelle

Antworten:

127

Verwenden Sie ein Objekt, wie die Leute sagen. Beachten Sie jedoch, dass Sie keine Ganzzahlschlüssel haben können. JavaScript konvertiert die Ganzzahl in eine Zeichenfolge . Die folgenden Ausgaben 20, nicht undefiniert:

var test = {}
test[2300] = 20;
console.log(test["2300"]);
Claudiu
quelle
12
+1 Beachten Sie, dass dies sogar für Arrays gilt! siehe stackoverflow.com/questions/1450957/…
Bobince
1
@ Bobince: Intern sicher. Jedoch logisch , Arrays hat integer "Schlüssel".
Lightness - Rennen in Orbit
1
Bitte beachten Sie, dass die Verwendung von Integer als Schlüssel die Länge Ihres Arrays ändert. Sie sollten auf jeden Fall stattdessen Object verwenden. Ich wollte nur die Facebook-ID als Schlüssel verwenden, und JSON.stringify würde meinen Computer zum Absturz bringen;)
Krystian
2
@LightnessRacesinOrbit Die internen Details können dennoch herauslaufen und Sie beißen. Sehen Sie sich diese vereinfachte Version von dem an, was mir heute begegnet ist: jsfiddle.net/cincodenada/pseujLex/2 Sie mag im reduzierten Zustand erfunden erscheinen, war aber ein sinnlicher Teil eines größeren Skripts (und ist in CoffeeScript etwas weniger erfunden : jsfiddle.net/ cincodenada / oojr7Ltn / 2 ). Dieses scheinbare Implementierungsdetail hat mich heute ein gutes Stück Fehlersuche gekostet.
Cincodenada
1
Ein kleiner Hinweis für nicht ganze Zahlen: 0.25und .25in dieselbe Zeichenfolge auflösen "0.25". Also , wenn Sie gebrochene Schlüssel verwenden, können Sie die Eigenschaft eines numerisch eingestellten Schlüssels abrufen 0.25verwenden 0.25, .25, "0.25"aber nicht ".25".
Sandy Gifford
34

Sie können einfach ein Objekt verwenden:

var test = {}
test[2300] = 'Some string';
Annie
quelle
16
Wird immer noch auf Schnur gegossen.
Draw010
1
@ draw010 Ja, die Objekte von Javascript erlauben die Indizierung nur mit Zeichenfolgen.
Pithikos
22

Wie die Leute sagen, konvertiert JavaScript eine Zahlenfolge in eine Ganzzahl, so dass es nicht möglich ist, sie direkt in einem assoziativen Array zu verwenden, aber Objekte funktionieren für Sie auf ähnliche Weise, wie ich denke.

Sie können Ihr Objekt erstellen:

var object = {};

Und fügen Sie die Werte hinzu, wenn das Array funktioniert:

object[1] = value;
object[2] = value;

Dies wird Ihnen geben:

{
  '1': value,
  '2': value
}

Danach können Sie wie ein Array in anderen Sprachen darauf zugreifen und den Schlüssel erhalten:

for(key in object)
{
   value = object[key] ;
}

Ich habe getestet und funktioniert.

Jesuslg123
quelle
17

Wenn der Anwendungsfall Daten in einer Sammlung speichert, stellt ECMAScript 6 den MapTyp bereit .

Es ist nur schwerer zu initialisieren.

Hier ist ein Beispiel:

const map = new Map();
map.set(1, "One");
map.set(2, "Two");
map.set(3, "Three");

console.log("=== With Map ===");

for (const [key, value] of map) {
    console.log(`${key}: ${value} (${typeof(key)})`);
}

console.log("=== With Object ===");

const fakeMap = {
    1: "One",
    2: "Two",
    3: "Three"
};

for (const key in fakeMap) {
    console.log(`${key}: ${fakeMap[key]} (${typeof(key)})`);
}

Ergebnis:

=== With Map ===
1: One (number)
2: Two (number)
3: Three (number)
=== With Object ===
1: One (string)
2: Two (string)
3: Three (string)
Pragmateek
quelle
11

Andere Antworten zusammenstellen:

Objekt

var test = {};

Wenn Sie eine Zahl als Schlüssel für eine neue Eigenschaft verwenden, wird die Zahl zu einer Zeichenfolge:

test[2300] = 'Some string';
console.log(test['2300']);
// Output: 'Some string'

Wenn Sie mit derselben Nummer auf den Wert der Eigenschaft zugreifen, wird die Nummer erneut in eine Zeichenfolge umgewandelt:

console.log(test[2300]);
// Output: 'Some string'

Wenn Sie die Schlüssel vom Objekt erhalten, werden sie jedoch nicht wieder in Zahlen umgewandelt:

for (var key in test) {
    console.log(typeof key);
}
// Output: 'string'

Karte

ECMAScript 6 ermöglicht die Verwendung des Map-Objekts ( Dokumentation , Vergleich mit Object ). Wenn Ihr Code lokal interpretiert werden soll oder die ECMAScript 6-Kompatibilitätstabelle für Ihre Zwecke grün genug aussieht, sollten Sie eine Karte verwenden:

var test = new Map();
test.set(2300, 'Some string');
console.log(test.get(2300));
// Output: 'Some string'

Es wird keine Typkonvertierung zum Guten und zum Schlechten durchgeführt:

console.log(test.get('2300'));
// Output: undefined
test.set('2300', 'Very different string');
console.log(test.get(2300));
// Output: 'Some string'
Wordbug
quelle
4

Verwenden Sie ein Objekt anstelle eines Arrays. Arrays in JavaScript sind keine assoziativen Arrays. Sie sind Objekte mit Magie, die mit Eigenschaften verknüpft sind, deren Namen wie Ganzzahlen aussehen. Diese Magie ist nicht das, was Sie wollen, wenn Sie sie nicht als traditionelle Array-ähnliche Struktur verwenden.

var test = {};
test[2300] = 'some string';
console.log(test);
bdukes
quelle
1
Sie können assoziative Arrays sein, aber nur, weil sie auch Objekte sind, für die benannte Eigenschaften festgelegt werden können. Aber das macht die Dinge nur lächerlich verwirrend, und so sind Objekte viel besser zu verwenden.
Graza
Arrays können niemals assoziative Graza sein. Wenn Sie versuchen, Schlüssel in einem Array zu verwenden und diese dann zu durchlaufen, werden Sie feststellen, dass Sie auch alle Standardmethoden und -eigenschaften von Arrays durchlaufen -> nicht sehr wünschenswert.
Swizec Teller
@ Swizec - genau deshalb habe ich "lächerlich verwirrend" gesagt. Sie können ein Array als assoziatives Array verwenden - das heißt als Name / Wert-Paare, aber Sie möchten sie niemals wiederholen! (Ich habe nur auf eine technische Besonderheit hingewiesen, definitiv nichts, was ich überhaupt empfehlen würde)
Graza
Ja, aber wenn sie iteriert werden, sind sie nicht in einer bestimmten Reihenfolge (dh die Reihenfolge ist nicht garantiert), was der Punkt der Nummerierung wäre, also ist es viel schlimmer als nur verwirrend.
Julix
3

Versuchen Sie es mit einem Objekt, nicht mit einem Array:

var test = new Object(); test[2300] = 'Some string';
Jeff Hammerbacher
quelle
3
Dies ist definitiv der richtige Weg. Auf diese Weise erstellen Sie kein Array mit 2300 Einträgen, um eine einzelne Zeichenfolge zu speichern.
Krystian
2
@Krystian JS-Arrays sind gefälschte Arrays. Führen var a = []; a[Math.pow(2, 30)] = 'hello';Sie es aus und Sie werden nicht sehen, dass die Browser- / Speicherauslastung um mehr als ein Gigabyte a.lengthansteigt , aber Sie werden 1073741824 sehen. VMs speichern eindeutig einige "Arrays" unter Verwendung einer anderen Datenstruktur, ich vermute einfach eine Hashtabelle, zumindest wenn Sie sind ausreichend spärlich.
Andy
2

Ruft den Wert für eine assoziative Array-Eigenschaft ab, wenn der Eigenschaftsname eine Ganzzahl ist:

Beginnend mit einem assoziativen Array, bei dem die Eigenschaftsnamen Ganzzahlen sind:

var categories = [
    {"1": "Category 1"},
    {"2": "Category 2"},
    {"3": "Category 3"},
    {"4": "Category 4"}
];

Elemente in das Array verschieben:

categories.push({"2300": "Category 2300"});
categories.push({"2301": "Category 2301"});

Durchlaufen Sie das Array und machen Sie etwas mit dem Eigenschaftswert.

for (var i = 0; i < categories.length; i++) {
    for (var categoryid in categories[i]) {
        var category = categories[i][categoryid];
        // Log progress to the console
        console.log(categoryid + ": " + category);
        //  ... do something
    }
}

Die Konsolenausgabe sollte folgendermaßen aussehen:

1: Category 1
2: Category 2
3: Category 3
4: Category 4
2300: Category 2300
2301: Category 2301

Wie Sie sehen können, können Sie die assoziative Array-Einschränkung umgehen und einen Eigenschaftsnamen als Ganzzahl festlegen.

HINWEIS: Das assoziative Array in meinem Beispiel ist der JSON-Inhalt, den Sie haben würden, wenn Sie ein Dictionary <string, string> [] -Objekt serialisieren würden.

Jason Williams
quelle
0

Verwenden Sie ein Objekt - mit einer Ganzzahl als Schlüssel - anstelle eines Arrays.

Upperstage
quelle
0

Manchmal verwende ich Präfixe für meine Schlüssel. Beispielsweise:

var pre = 'foo',
    key = pre + 1234

obj = {};

obj[key] = val;

Jetzt haben Sie kein Problem damit, auf sie zuzugreifen.

pictus
quelle