Javascript foreach-Schleife für assoziatives Array-Objekt

181

Warum iteriert meine for-each-Schleife nicht über mein assoziatives JavaScript-Array-Objekt?

// defining an array
var array = [];

// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

BEARBEITEN: jQuery each()könnte hilfreich sein: https://api.jquery.com/jQuery.each/

Szymon Toda
quelle
1
Sie erstellen ein Array, verwenden es dann aber als Karte. Es sieht so aus, als ob Sie stattdessen ein einfaches Objekt möchten.
Jon
4
Es gibt keine Dinge wie associative arraysin JS: Es ist entweder ein einfaches Array oder ein Objekt. Nichts verhindert das Hinzufügen nicht numerischer Eigenschaften Array, aber das macht es nicht associative- insbesondere lengthwerden diese Eigenschaften von Eigenschaften nicht automatisch gezählt.
raina77ow
3
Betreff: In JS gibt es keine assoziativen Arrays. - anders formuliert: JavaScript verwendet den Namen "Object" anstelle des Namens "assoziatives Array". Es hat jedoch keine ".length" -Eigenschaft.
Jesse Chisholm

Antworten:

313

Die .lengthEigenschaft verfolgt nur Eigenschaften mit numerischen Indizes (Schlüsseln). Sie verwenden Zeichenfolgen für Schlüssel.

Du kannst das:

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

Um sicher zu gehen, ist es in solchen Schleifen eine gute Idee, sicherzustellen, dass keine der Eigenschaften unerwartete Ergebnisse der Vererbung sind:

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

Bearbeiten - Es ist jetzt wahrscheinlich eine gute Idee zu beachten, dass die Object.keys()Funktion in modernen Browsern und in Node usw. verfügbar ist. Diese Funktion gibt die "eigenen" Schlüssel eines Objekts als Array zurück:

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

Die an übergebene Rückruffunktion .forEach()wird mit jedem Schlüssel und dem Schlüsselindex in dem von zurückgegebenen Array aufgerufen Object.keys(). Es wird auch das Array übergeben, durch das die Funktion iteriert, aber dieses Array ist für uns nicht wirklich nützlich. Wir brauchen das ursprüngliche Objekt . Darauf kann direkt über den Namen zugegriffen werden, aber (meiner Meinung nach) ist es etwas schöner, ihn explizit zu übergeben, indem ein zweites Argument an .forEach()das ursprüngliche Objekt übergeben wird, das wie thisim Rückruf gebunden wird . (Ich habe gerade gesehen, dass dies in einem Kommentar unten vermerkt wurde.)

Spitze
quelle
Was ist das var arr_jq_TabContents = {};? Ich meine {}
Szymon Toda
1
@ Ultra ist ein leeres Objektliteral. Dies bedeutet lediglich, dass die Variable mit einem Verweis auf ein neues leeres Objekt initialisiert wird.
Pointy
@Ultra Sie benötigen keine Array-Instanz, da Sie sie in diesem Code nicht wie ein JavaScript-Array verwenden. JavaScript hat keine "assoziativen Arrays" wie einige andere Sprachen.
Pointy
1
Was ist der Unterschied zwischen Zuweisen []und {}? Nur die verschiedenen Prototypen?
SoonDead
8
Anstatt hasOwnProperty zu verwenden, sollte es in allen modernen Webbrowsern möglich sein, über die Schlüssel eines Objekts zu iterieren, indem: Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
Gregory Bell
79

Dies ist ein sehr einfacher Ansatz. Der Vorteil ist, dass Sie auch Schlüssel erhalten können:

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

Für ES6:

array.forEach(value => {
  console.log(value)
})  

Für ES6: (Wenn Sie Wert, Index und das Array selbst möchten)

array.forEach((value, index, self) => {
  console.log(value, index, self)
})  
Tika
quelle
12
Nicht varin Schleifen verwenden, die ein nicht vorhandenes Scoping vorschlagen. Verwenden Sie varvor der Schleife oder letin der Schleife.
Ceving
2
@ceving, kannst du mehr darüber erklären, warum du nicht var in Schleifen verwendest? Ich komme aus C ++ / PHP und verstehe das nicht. Scoping existiert zwar in der Schleife, ist aber nur vorübergehend, daher bin ich mir nicht sicher, was Sie meinen.
Dennis
6
@Dennis In den meisten Sprachen forgeneriert eine Variablendeklaration in einer Schleife einen Bereich, der auf den Hauptteil der forSchleife beschränkt ist. In JavaScript ist eine von deklarierte Variable varjedoch immer eine globale Funktion, selbst wenn Sie sie in eine forSchleife schreiben . Siehe hier: davidwalsh.name/for-and-against-let
Uhr
1
Nicht Speicherlecks an sich, sondern definitiv "Speicherverluste". varin Javascript erstellt Variablen im Speicher, auch nachdem die Schleife abgeschlossen ist.
Ahnbizcad
Ich denke, der Sinn dieser Kommentare bezüglich der Verwendung von "var" besteht darin, jetzt "let" im Allgemeinen, aber speziell in einer Schleife zu verwenden. Die Gründe wurden oben erläutert, aber zusammenfassend liegt es am Bereich. "Var" erstellt einen globalen Bereich.
DeeZone
6

Es gibt bereits einige einfache Beispiele, aber ich stelle anhand Ihrer Formulierung fest, dass Sie wahrscheinlich aus einem PHP-Hintergrund stammen und erwarten, dass JavaScript auf die gleiche Weise funktioniert - dies ist jedoch nicht der Fall. Ein PHP unterscheidet arraysich sehr von einem JavaScript Array.

In PHP kann ein assoziatives Array das meiste tun, was ein numerisch indiziertes Array kann (die array_*Funktionen funktionieren, Sie können count()es usw.). Sie erstellen einfach ein Array und beginnen mit der Zuweisung zu Zeichenfolgenindizes anstelle von numerischen.

In JavaScript ist alles ein Objekt (mit Ausnahme der Grundelemente: Zeichenfolge, numerisch, boolesch), und Arrays sind eine bestimmte Implementierung, mit der Sie numerische Indizes erstellen können. Alles , was zu einer Reihe geschoben wird seine Wirkung length, und kann gegenüber der Verwendung Array Methoden wiederholt werden ( map, forEach, reduce, filter, find, etc.) Da jedoch alles ein Objekt ist, du bist immer frei einfach assign Eigenschaften, denn das ist etwas , was Sie tun , um jedes Objekt. Die eckige Klammer ist einfach eine andere Möglichkeit, auf eine Eigenschaft zuzugreifen. In Ihrem Fall also:

array['Main'] = 'Main Page';

ist eigentlich gleichbedeutend mit:

array.Main = 'Main Page';

Aus Ihrer Beschreibung geht hervor, dass Sie ein 'assoziatives Array' möchten, aber für JavaScript ist dies ein einfacher Fall, bei dem ein Objekt als Hashmap verwendet wird. Ich weiß auch, dass es ein Beispiel ist, aber vermeiden Sie nicht aussagekräftige Namen, die nur den Variablentyp (z. B. array) beschreiben, und Namen, die darauf basieren, was er enthalten sollte (z pages. B. ). Einfache Objekte haben nicht viele gute direkte Wege zu iterieren, wir werden so oft drehen dann in Arrays zuerst unter Verwendung von ObjectMethoden ( Object.keysin diesem Fall - es gibt auch entriesund valuesgerade jetzt zu einigen Browsern hinzugefügt werden) , die wir können Schleife.

// assigning values to corresponding keys
const pages = {
  Main: 'Main page',
  Guide: 'Guide page',
  Articles: 'Articles page',
  Forum: 'Forum board',
};

Object.keys(pages).forEach((page) => console.log(page));
Josh aus Qaribou
quelle
4

arr_jq_TabContents[key] sieht das Array als 0-Index-Form.

MSO
quelle
4

Hier ist eine einfache Möglichkeit, ein assoziatives Array als generischen Objekttyp zu verwenden:

Object.prototype.forEach = function(cb){
   if(this instanceof Array) return this.forEach(cb);
   let self = this;
   Object.getOwnPropertyNames(this).forEach(
      (k)=>{ cb.call(self, self[k], k); }
   );
};

Object({a:1,b:2,c:3}).forEach((value, key)=>{ 
    console.log(`key/value pair: ${key}/${value}`);
});

Chouettou
quelle
4

Wenn die Datei node.js oder der Browser unterstützt wird Object.entries(), kann sie als Alternative zur Verwendung verwendet werden Object.keys()( https://stackoverflow.com/a/18804596/225291 ).

const h = {
  a: 1,
  b: 2
};

Object.entries(h).forEach(([key, value]) => console.log(value));
// logs 1, 2

In diesem Beispiel wird forEachdie Destrukturierungszuweisung eines Arrays verwendet.

Banyan
quelle
1

Dies ist in den meisten Fällen (im Wesentlichen) falsch:

var array = [];
array["Main"] = "Main page";

Dadurch wird eine Nicht-Element-Eigenschaft für das Array mit dem Namen erstellt Main. Obwohl Arrays Objekte sind, möchten Sie normalerweise keine Nicht-Elementeigenschaften für sie erstellen.

Wenn Sie arrayanhand dieser Namen indizieren möchten , verwenden Sie normalerweise ein Mapoder ein einfaches Objekt, kein Array.

Mit einem Map(ES2015 +), den ich nennen werde, mapweil ich kreativ bin:

let map = new Map();
map.set("Main", "Main page");

Sie durchlaufen dann die Iteratoren mit von seinen values, keysoder entriesMethoden, zum Beispiel:

for (const value of map.values()) {
    // Here, `value` will be `"Main page"`, etc.
}

Verwenden eines einfachen Objekts, das ich kreativ nennen werde obj:

let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`

Sie würde dann seinen Inhalt mit iterieren Object.keys, Object.valuesoder Object.entries, zum Beispiel:

for (const value of Object.values(proches_X)) {
    // Here, `value` will be `"Main page"`, etc.
}
TJ Crowder
quelle
0

var obj = {
  no: ["no", 32],
  nt: ["no", 32],
  nf: ["no", 32, 90]
};

count = -1; // which must be static value
for (i in obj) {
  count++;
  if (obj.hasOwnProperty(i)) {
    console.log(obj[i][count])
  };
};

In diesem Code habe ich die Brackets-Methode für Aufrufwerte im Array verwendet, da sie ein Array enthielt, jedoch kurz die Idee, dass eine Variable i einen Eigenschaftsschlüssel und eine Schleife mit beiden Werten des zugeordneten Arrays hat

perfekte Methode, wenn Sie interessiert sind, drücken Sie gerne

Dev-Wb Ahmed
quelle
Sie führen keine Schleife durch ein Array, sondern eine Schleife durch ein Objekt, dessen Schlüssel Arrays enthalten. Bitte lesen Sie die Frage und sehen Sie sich das Beispiel an.
Pedro Joaquín
0

Du kannst das

var array = [];

// assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";


array.forEach(value => {
    console.log(value)
})
Shuvro
quelle