Frage Durchlaufen Sie ein Array in JavaScript


In Java können Sie ein for Schleife um Objekte in einem Array wie folgt zu traversieren:

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

Können Sie das gleiche in JavaScript tun?


2415
2018-06-10 00:04


Ursprung


Antworten:


Verwenden Sie eine sequenzielle for Schleife:

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    alert(myStringArray[i]);
    //Do something
}

@zipcodeman schlägt die Verwendung des for...in Anweisung, sondern zum Iterieren von Arrays for-in sollte vermieden werden, dass diese Aussage gemeint ist aufzählen Objekteigenschaften.

Es sollte nicht für Array-ähnliche Objekte verwendet werden, weil:

  • Die Reihenfolge der Iterationen ist nicht garantiert. Die Array-Indizes werden möglicherweise nicht in numerischer Reihenfolge aufgerufen.
  • Vererbte Eigenschaften werden ebenfalls aufgelistet.

Der zweite Punkt ist, dass es Ihnen viele Probleme bereiten kann, zum Beispiel, wenn Sie das erweitern Array.prototype Objekt, um eine Methode dort aufzunehmen, wird diese Eigenschaft auch aufgelistet.

Beispielsweise:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
  alert(array[i]);
}

Der obige Code wird alarmieren, "a", "b", "c" und "foo!".

Dies ist besonders dann ein Problem, wenn Sie eine Bibliothek verwenden, die stark auf der Unterstützung von nativen Prototypen basiert (wie z. B. MooTools).

Das for-in Aussage wie ich schon sagte ist da aufzählen Objekteigenschaften, zum Beispiel:

var obj = {
  "a": 1,
  "b": 2,
  "c": 3
};

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) { 
  // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

Im obigen Beispiel hasOwnProperty Methode erlaubt Ihnen, nur aufzuzählen eigene EigenschaftenDas sind nur die Eigenschaften, die das Objekt physisch besitzt, keine vererbten Eigenschaften.

Ich würde Ihnen empfehlen, den folgenden Artikel zu lesen:


3050
2018-06-10 00:07



Ja, aber nur, wenn Ihre Implementierung die for...of Feature eingeführt in ECMAScript 2015 (die "Harmony" Version).

Es funktioniert so:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

Oder besser noch, da ECMAScript 2015 auch block-scoped Variablen via bereitstellt let und const:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

Viele JavaScript-Entwickler arbeiten jedoch immer noch in einer Umgebung, die noch nicht da ist - vor allem, wenn Code geschrieben wird, der in Webbrowsern ausgeführt wird, wo die Websiteentwickler oft nicht sicher sein können, welchen Browser / welche Version ihre Clients verwenden.

Wenn Sie davon ausgehen können, dass der JavaScript-Interpreter mit dem Bisherige Edition der ECMAScript - Spezifikation (die z. B. Versionen von Internet Explorer vor 9 ausschließt), dann können Sie die forEach Iterator-Methode anstelle einer Schleife. In diesem Fall übergeben Sie eine Funktion, die für jedes Element im Array aufgerufen werden soll:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

Aber selbst wenn das zu viel ist, und Sie wollen etwas, das funktioniert alle Versionen von JavaScript, dann müssen Sie eine explizite Zählschleife verwenden. Die sicherste Version, die sparse Arrays richtig behandelt, ist etwa so:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

Zuweisen des Längenwerts zu der lokalen Variablen (im Gegensatz zum Einschließen des vollständigen Werts myStringArray.length Ausdruck in der Schleifenbedingung) kann einen signifikanten Unterschied in der Leistung machen, da es jedes Mal eine Eigenschaftssuche überspringt; mit Rhino auf meinem Rechner beträgt die Beschleunigung 43%.

In der Loop-Initialisierungsklausel sehen Sie häufig das Caching der Länge:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

Das for...in Syntax, die von anderen erwähnt wird, dient dazu, die Eigenschaften eines Objekts zu durchlaufen; da ein Array in JavaScript nur ein Objekt mit numerischen Eigenschaftsnamen ist (und automatisch aktualisiert wird) lengthEigenschaft), können Sie theoretisch ein Array damit durchlaufen. Das Problem ist jedoch, dass es sich nicht auf die numerischen Eigenschaftswerte beschränkt (bedenken Sie, dass gerade Methoden tatsächlich nur Eigenschaften sind, deren Wert eine Closure ist), noch iteriert es über diese in numerischer Reihenfolge. deshalb, die for...in Syntax sollte nicht für das Durchlaufen von Arrays verwendet werden.


868
2018-04-16 02:03



Sie können verwenden mapDies ist eine funktionale Programmiertechnik, die auch in anderen Sprachen verfügbar ist Python und Haskell.

[1,2,3,4].map( function(item) {
     alert(item);
})

Die allgemeine Syntax lautet:

array.map(func)

Im Algemeinen func würde einen Parameter nehmen, der ein Element des Arrays ist. Aber im Fall von JavaScript kann es einen zweiten Parameter annehmen, der der Index des Gegenstands ist, und ein dritter Parameter, der das Feld selbst ist.

Der Rückgabewert von array.map ist ein anderes Array, also können Sie es wie folgt verwenden:

var x = [1,2,3,4].map( function(item) {return item * 10;});

Und jetzt ist x [10,20,30,40].

Sie müssen die Funktion nicht inline schreiben. Es könnte eine separate Funktion sein.

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

was wäre gleichbedeutend mit:

 for (item in my_list) {item_processor(item);}

Außer du bekommst das nicht new_list.


391
2018-06-10 00:09



In JavaScript ist es nicht ratsam, ein Array mit einer For-In-Schleife zu durchlaufen, aber es ist besser, eine For-Schleife zu verwenden, wie zum Beispiel:

for(var i=0, len=myArray.length; i < len; i++){}

Es ist auch optimiert ("Caching" der Array-Länge). Wenn Sie mehr erfahren möchten, lies meinen Beitrag zu diesem Thema.


102
2017-12-07 07:24



für (var s von myStringArray) {

(Direkt auf Ihre Frage antworten: Jetzt können Sie!)

Die meisten anderen Antworten sind richtig, aber sie erwähnen das (wie dies geschrieben wurde) nicht ECMA-Skript 6 2015 bringt einen neuen Mechanismus für die Iteration, die for..of Schleife.

Diese neue Syntax ist die eleganteste Möglichkeit, ein Array in JavaScript zu durchlaufen (solange Sie den Iterationsindex nicht benötigen), aber von den Browsern noch nicht weitgehend unterstützt.

Es funktioniert derzeit mit Firefox 13+, Chrome 37+ und funktioniert nativ nicht mit anderen Browsern (siehe Browserkompatibilität weiter unten). Zum Glück haben wir JS Compiler (wie Babel), die es uns heute ermöglichen, die Funktionen der nächsten Generation zu nutzen.

Es funktioniert auch auf Node (ich habe es auf Version 0.12.0 getestet).

Iterieren eines Arrays

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

Iterieren eines Arrays von Objekten

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

Iteration eines Generators:

(Beispiel extrahiert aus https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

Kompatibilitätstabelle: http://kangax.github.io/es5-compat-table/es6/#For..of Schleifen

Spezifikation:  http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}


92
2017-08-11 15:54



Opera, Safari, Firefox und Chrome haben jetzt alle eine Reihe von verbesserten Array-Methoden zur Optimierung vieler gängiger Loops.

Sie brauchen möglicherweise nicht alle von ihnen, aber sie können sehr nützlich sein, oder würden, wenn jeder Browser sie unterstützt.

Mozilla Labs veröffentlichte die Algorithmen, die sie und Webkit beide verwenden, so dass Sie sie selbst hinzufügen können.

Filter Gibt ein Array von Elementen zurück, die eine Bedingung oder einen Test erfüllen.

jeden gibt true zurück, wenn jedes Array-Element den Test besteht.

etwas gibt true zurück, wenn einer den Test besteht.

für jede Führt für jedes Array-Element eine Funktion aus und gibt nichts zurück.

Karte ist wie forEach, aber es gibt ein Array der Ergebnisse der Operation für jedes Element zurück.

Diese Methoden nehmen alle eine Funktion für ihr erstes Argument an und haben ein optionales zweites Argument, das ein Objekt ist, dessen Gültigkeitsbereich Sie den Array-Mitgliedern beim Durchlaufen der Funktion aufzwingen wollen.

Ignoriere es, bis du es brauchst.

Index von und letzterIndexOf finde die passende Position des ersten oder letzten Elements, das genau zu seinem Argument passt.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();

81
2018-06-10 02:43



Benutze die while-Schleife ...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

Protokolle: "Eins", "Zwei", "Drei"

Und für die umgekehrte Reihenfolge eine noch effizientere Schleife

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

Protokolle: "drei", "zwei", "eins"

Oder das Klassische for Schleife

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

Protokolle: "Eins", "Zwei", "Drei"

Referenz: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/


62
2018-01-05 09:15



Einführung

Seit meiner Zeit am College habe ich in Java, JavaScript, Pascal, ABAP, PHP, Progress 4GL, C / C ++ und möglicherweise ein paar andere Sprachen, an die ich momentan nicht denken kann.

Während alle ihre eigenen linguistischen Eigenheiten haben, teilt jede dieser Sprachen viele der gleichen grundlegenden Konzepte. Solche Konzepte umfassen Verfahren / Funktionen, IF- Aussagen, FOR-Schlaufen und WHILE-Schlaufen.


Ein traditionelles for-Schleife

Ein traditionelles for Schleife hat drei Komponenten:

  1. Die Initialisierung: ausgeführt, bevor der Look-Block das erste Mal ausgeführt wird
  2. Die Bedingung: prüft jedes Mal vor der Ausführung des Schleifenblocks eine Bedingung und beendet die Schleife bei false
  3. Der nachträgliche Einfall: Wird jedes Mal ausgeführt, nachdem der Schleifenblock ausgeführt wurde

Diese drei Komponenten sind voneinander durch a getrennt ; Symbol. Der Inhalt für jede dieser drei Komponenten ist optional, was bedeutet, dass das Folgende minimal ist for Schleife möglich:

for (;;) {
    // Do stuff
}

Natürlich müssen Sie ein if(condition === true) { break; }  oder if(condition === true) { return; } irgendwo drinnen for- Schleife, damit es aufhört zu laufen.

Normalerweise wird die Initialisierung verwendet, um einen Index zu deklarieren, die Bedingung wird verwendet, um diesen Index mit einem minimalen oder maximalen Wert zu vergleichen, und der nachträgliche Einschub wird verwendet, um den Index zu erhöhen:

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

Mit einem traditionellen for Schleife, um ein Array zu durchlaufen

Die traditionelle Art, ein Array zu durchlaufen, ist dies:

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

Oder, wenn Sie lieber rückwärts laufen möchten, tun Sie dies:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

Es sind jedoch viele Variationen möglich, wie zum Beispiel diese:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

... oder dieses ...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

... oder dieses:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

Was am besten funktioniert, hängt weitgehend vom persönlichen Geschmack und dem spezifischen Anwendungsfall ab, den Sie implementieren.

Beachten Sie, dass jede dieser Varianten von allen Browsern unterstützt wird, einschließlich sehr sehr alten!


EIN while Schleife

Eine Alternative zu a for Schleife ist a whileSchleife. Um ein Array zu durchlaufen, können Sie Folgendes tun:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

Wie traditionell for Schleifen, while Loops werden sogar von den ältesten Browsern unterstützt.

Beachten Sie auch, dass jede while-Schleife als a überschrieben werden kann for Schleife. Zum Beispiel, die while Die obige Schleife verhält sich genau so wie diese for-Schleife:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...in und for...of

In JavaScript können Sie dies auch tun:

for (i in myArray) {
    console.log(myArray[i]);
}

Dies sollte jedoch mit Vorsicht gehandhabt werden, da es sich nicht wie ein traditionelles verhält for Schleife in allen Fällen, und es gibt mögliche Nebenwirkungen, die berücksichtigt werden müssen. Sehen Warum ist "for ... in" mit Array Iteration eine schlechte Idee? für mehr Details.

Als Alternative zu for...ingibt es jetzt auch für for...of. Das folgende Beispiel zeigt den Unterschied zwischen a for...of Schleife und a for...in Schleife:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

Darüber hinaus müssen Sie berücksichtigen, dass keine Version von Internet Explorer unterstützt for...of (Kante 12+ tut) und das for...in benötigt mindestens Internet Explorer 10.


Array.prototype.forEach()

Eine Alternative zu for-loops ist Array.prototype.forEach(), die die folgende Syntax verwendet:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() wird von allen modernen Browsern sowie Internet Explorer 9 und höher unterstützt.


Bibliotheken

Schließlich haben viele Utility-Bibliotheken auch ihre eigenen foreach Variation. AFAIK, die drei beliebtesten sind diese:

jQuery.each(), im jQuery:

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each(), im Underscore.js:

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach(), im Lodash.js:

_.forEach(myArray, function(value, key) {
    console.log(value);
});

48
2018-02-29 18:56