Voor elk over een array in JavaScript

Hoe kan ik alle items in een array doorlopen met JavaScript?

Ik dacht dat het ongeveer zo was:

forEach(instance in theArray)

Waar theArray mijn array is, maar dit lijkt onjuist te zijn.


Antwoord 1, autoriteit 100%

TL;DR

  • Uw beste weddenschappen zijn meestal

    • een for-of-lus (alleen ES2015+; spec | MDN) – eenvoudig en async-vriendelijk
    • forEach (alleen ES5+; spec | MDN) (of verwanten some en dergelijke) – niet async-vriendelijk (maar zie details)
    • een eenvoudige ouderwetse for-lus – async-vriendelijk
    • (zelden) for-in met beveiligingenasync-vriendelijk
  • Enkele snelle “niet doen”:

    • Gebruik for-in niet tenzij je het met voorzorgsmaatregelen gebruikt of op zijn minst weet waarom het je zou kunnen bijten.
    • Gebruik map niet als je de retourwaarde niet gebruikt.
      (Er is helaas iemand die map [spec / MDN] alsof het forEach maar daar is het niet voor. Als u de array niet gebruikt het maakt, gebruik geen map.)
    • Gebruik forEach niet als de callback asynchroon werkt en u wilt dat de forEach wacht tot dat werk is gedaan (omdat het niet).

Maar er is veel meer te ontdekken, lees verder…


JavaScript heeft krachtige semantiek voor het doorlopen van arrays en array-achtige objecten. Ik heb het antwoord in twee delen opgesplitst: opties voor echte arrays en opties voor dingen die gewoon array-zoals zijn, zoals het object arguments, andere itereerbare objecten ( ES2015+), DOM-verzamelingen, enzovoort.

Ok, laten we eens kijken naar onze opties:

Voor werkelijke arrays

Je hebt vijf opties (twee worden in principe voor altijd ondersteund, een andere toegevoegd door ECMAScript 5 ["ES5”], en nog twee toegevoegd in ECMAScript 2015 (“ES2015”, ook bekend als “ES6”):

  1. Gebruik for-of (gebruik impliciet een iterator) (ES2015+)
  2. Gebruik forEach en gerelateerd (ES5+)
  3. Gebruik een eenvoudige for-lus
  4. Gebruik for-in correct
  5. Gebruik expliciet een iterator (ES2015+)

(Je kunt die oude specificaties hier bekijken: ES5, ES2015, maar beide zijn vervangen; het huidige concept van de editor is altijd hier.)

Details:

1. Gebruik for-of (gebruik impliciet een iterator) (ES2015+)

ES2015 heeft iterators en iterables toegevoegd naar JavaScript. Arrays zijn itereerbaar (net als strings, maps en Sets, evenals DOM-verzamelingen en lijsten, zoals u later zult zien). Itereerbare objecten bieden iterators voor hun waarden. De nieuwe instructie for-of doorloopt de waarden die door een iterator worden geretourneerd:

const a = ["a", "b", "c"];
for (const val of a) { // You can use `let` instead of `const` if you like
    console.log(val);
}
// a
// b
// c

Antwoord 2, autoriteit 7%

Opmerking: dit antwoord is hopeloos verouderd. Bekijk voor een modernere aanpak de methoden die beschikbaar zijn op een reeks. Interessante methoden kunnen zijn:

  • voor elk
  • kaart
  • filter
  • zip
  • verminderen
  • elke
  • sommige

De standaardmanier om een ​​array in JavaScript te herhalen, is een vanille for-loop:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

Houd er echter rekening mee dat deze benadering alleen goed is als je een dichte array hebt en elke index wordt ingenomen door een element. Als de array schaars is, kun je met deze aanpak prestatieproblemen tegenkomen, omdat je veel indices zult herhalen die echt niet in de array voorkomen. In dit geval is een for .. in-loop misschien een beter idee. Echter moet u de juiste voorzorgsmaatregelen gebruiken om ervoor te zorgen dat alleen de gewenste eigenschappen van de array (dat wil zeggen, de array-elementen) worden toegepast, aangezien de for..in -loop wordt ook geteld in oudere browsers, of als de extra eigenschappen zijn gedefinieerd als enumerable.

In ECMAScript 5 zal er een forEach-methode zijn op het array-prototype, maar het wordt niet ondersteund in oudere browsers. Dus om het consistent te kunnen gebruiken, moet je een omgeving hebben die het ondersteunt (bijvoorbeeld Node. js voor server-side JavaScript), of gebruik een “Polyfill”. De Polyfill voor deze functionaliteit is echter triviaal en omdat het de code gemakkelijker leesbaar maakt, is het een goede polyfill om op te nemen.


Antwoord 3, autoriteit 3%

Als je de bibliotheek jQuery gebruikt, kun je jQuery.each:

$.each(yourArray, function(index, value) {
  // do your stuff here
});

BEWERKEN:

Volgens de vraag wil de gebruiker code in javascript in plaats van jQuery, dus de bewerking is

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}

Antwoord 4, autoriteit 2%

Loop achteruit

Ik denk dat de reverse for-lus hier een vermelding verdient:

for (var i = array.length; i--; ) {
     // process array[i]
}

Voordelen:

  • Je hoeft geen tijdelijke len-variabele te declareren, of te vergelijken met array.length bij elke iteratie, die een van beide een minuutje optimalisatie kan zijn.
  • Het verwijderen van broers en zussen uit de DOM in omgekeerde volgorde is meestal efficiënter. (De browser hoeft minder elementen in zijn interne arrays te verplaatsen.)
  • Als u de array wijzigt tijdens het herhalen, op of na index i (u verwijdert bijvoorbeeld een item of voegt een item toe aan array[i]), dan zou een voorwaartse lus het item dat naar links is verschoven naar positie i overslaan, of het ide item dat naar rechts is verschoven opnieuw verwerken. In een traditionele for-lus zou i kunnen worden bijgewerkt om te verwijzen naar het volgende item dat moet worden verwerkt – 1, maar het eenvoudigweg omkeren van de iteratierichting is vaak een eenvoudiger en elegantere oplossing .
  • Bij het aanpassen of verwijderen van geneste DOM-elementen kan omgekeerde verwerking fouten omzeilen. Overweeg bijvoorbeeld om de innerHTML van een bovenliggend knooppunt te wijzigen voordat u de onderliggende knooppunten afhandelt. Tegen de tijd dat de onderliggende node wordt bereikt, wordt deze losgekoppeld van de DOM en vervangen door een nieuw gemaakt kind toen de innerHTML van de ouder werd geschreven.
  • Het is korter om te typen en lezen dan sommige andere beschikbare opties. Hoewel het verliest van forEach() en van ES6’s for ... of.

Nadelen:

  • Het verwerkt de items in omgekeerde volgorde. Als u een nieuwe array aan het bouwen was op basis van de resultaten, of dingen op het scherm afdrukte, zal de uitvoer natuurlijk worden omgekeerd ten opzichte van de oorspronkelijke volgorde.
  • Het herhaaldelijk invoegen van broers en zussen in de DOM als eerste kind om hun volgorde te behouden is minder efficiënt. (De browser zou dingen steeds weer naar rechts moeten verplaatsen.) Om DOM-knooppunten efficiënt en in de juiste volgorde te maken, loop je gewoon vooruit en voeg je zoals normaal toe (en gebruik je ook een “documentfragment”).
  • De omgekeerde lus is verwarrend voor junior ontwikkelaars. (U kunt dat als een voordeel beschouwen, afhankelijk van uw vooruitzichten.)

Moet ik het altijd gebruiken?

Sommige ontwikkelaars gebruiken standaard de reverse for loop, tenzij er een goede reden is om forwards te loopen.

Hoewel de prestatieverbeteringen meestal onbeduidend zijn, schreeuwt het een beetje:

“Doe dit gewoon met elk item in de lijst, de bestelling maakt me niet uit!”

In de praktijk is dat echter geen eigenlijk een betrouwbare indicatie van intentie, aangezien het niet te onderscheiden is van die momenten waarop u wel geeft om de volgorde, en echt nodig om in omgekeerde volgorde te herhalen. Er zou dus in feite een andere constructie nodig zijn om de “don’t care”-intentie nauwkeurig uit te drukken, iets dat momenteel niet beschikbaar is in de meeste talen, waaronder ECMAScript, maar dat bijvoorbeeld forEachUnordered() zou kunnen heten.

Als volgorde er niet toe doet, en efficiëntie een punt van zorg is (in de binnenste lus van een game of animatie-engine), dan kan het acceptabel zijn om de omgekeerde for-lus te gebruiken als uw doel- te patroon. Onthoud dat het zien van een omgekeerde for-lus in bestaande code niet noodzakelijkerwijs betekent dat de volgorde niet relevant is!

Het was beter om forEach()

. te gebruiken

Over het algemeen heb ik voor code op een hoger niveau waar duidelijkheid en veiligheid grotere zorgen zijn, eerder aanbevolen Array::forEach als uw standaardpatroon voor looping (hoewel ik tegenwoordig liever for..of). Redenen om forEach te verkiezen boven een omgekeerde lus zijn:

  • Het is duidelijker om te lezen.
  • Het geeft aan dat i niet binnen het blok zal worden verschoven (wat altijd een mogelijke verrassing is die zich verstopt in lange for en while lussen).
  • Het geeft je een vrije ruimte voor sluitingen.
  • Het vermindert het lekken van lokale variabelen en onbedoelde botsingen met (en mutatie van) externe variabelen.

Als je dan de omgekeerde for-lus in je code ziet, is dat een hint dat het om een ​​goede reden is omgekeerd (misschien een van de hierboven beschreven redenen). En het zien van een traditionele forward for loop kan erop wijzen dat er kan worden verschoven.

(Als de discussie over intentie voor jou geen zin heeft, kunnen jij en je code baat hebben bij het bekijken van de lezing van Crockford op Programmeerstijl en je hersenen.)

Het is nu nog beter te gebruiken for..of!

Er is discussie over de vraag of for..of of forEach() de voorkeur heeft:

  • Voor maximale browserondersteuning, for..of vereist een polyfill voor iterators, waardoor uw app iets langzamer wordt uitgevoerd en iets groter om te downloaden.

  • Daarom (en om het gebruik van map en filter aan te moedigen), sommige front-end stijlgidsen verbieden for..of volledig!

  • Maar de bovenstaande zorgen zijn niet van toepassing op Node.js-applicaties, waar for..of nu goed wordt ondersteund.

  • En verder await werkt niet binnen forEach(). Het gebruik van for..of is het duidelijkste patroon in dit geval.

Persoonlijk heb ik de neiging om alles te gebruiken wat het gemakkelijkst te lezen lijkt, tenzij prestatie of verkleining een belangrijk punt van zorg is geworden. Dus tegenwoordig gebruik ik liever for..of in plaats van forEach(), maar ik zal altijd map of filter of find of some indien van toepassing.
(In het belang van mijn collega’s gebruik ik zelden reduce.)


Hoe werkt het?

for (var i = 0; i < array.length; i++) { ... }   // Forwards
for (var i = array.length; i--; )    { ... }   // Reverse

Je zult merken dat i-- de middelste clausule is (waar we meestal een vergelijking zien) en de laatste clausule leeg is (waar we meestal i++ zien). Dat betekent dat i-- ook wordt gebruikt als de voorwaarde voor voortzetting. Cruciaal is dat het vóór elke iteratie wordt uitgevoerd en gecontroleerd.

  • Hoe kan het beginnen op array.length zonder te exploderen?

    Omdat i-- vóór elke iteratie wordt uitgevoerd, hebben we bij de eerste iteratie daadwerkelijk toegang tot het item op array.length - 1 wat problemen met Array-out-of-bounds undefined items voorkomt.

  • Waarom stopt het niet met herhalen vóór index 0?

    De lus stopt met herhalen wanneer de voorwaarde i-- evalueert tot een falsey-waarde (wanneer deze 0 oplevert).

    De truc is dat, in tegenstelling tot --i, de afsluitende operator i-- i verlaagt, maar de waarde vóór de verlaging. Uw console kan dit aantonen:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    Dus bij de laatste iteratie was i eerder 1 en de uitdrukking i-- verandert deze in 0 maar levert in feite 1 (waarheid) op, en dus verstrijkt de voorwaarde. Bij de volgende iteratie verandert i-- i in -1 maar levert 0 (falsey) op, waardoor de uitvoering vallen onmiddellijk uit de onderkant van de lus.

    In de traditionele forwards for loop zijn i++ en ++i onderling uitwisselbaar (zoals Douglas Crockford aangeeft). Maar in de omgekeerde for-lus, omdat onze afname ook onze voorwaarde-uitdrukking is, moeten we i-- gebruiken als we het item op index 0 willen verwerken.


Trivia

Sommige mensen tekenen graag een pijltje in de omgekeerde for-lus en eindigen met een knipoog:

for (var i = array.length; i --> 0 ;) {

De credits gaan naar WYL voor het tonen van de voordelen en gruwelen van de reverse for loop.


Antwoord 5

Sommige C-achtige talen gebruiken forEach opsommingen te doorlopen. In JavaScript wordt dit gedaan met de for..in lusstructuur:

var index,
    value;
for (index in obj) {
    value = obj[index];
}

Er is een addertje onder het gras. for..in doorloopt elk van de opsombare leden van het object en de leden op het prototype. Om te voorkomen dat u waarden leest die via het prototype van het object zijn overgenomen, hoeft u alleen maar te controleren of de eigenschap bij het object hoort:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

Bovendien heeft ECMAScript 5 een forEach methode om Array.prototype die kan worden gebruikt om een ​​array op te sommen met behulp van een calback (de polyfill staat in de documenten, dus je kunt het nog steeds gebruiken voor oudere browsers):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

Het is belangrijk op te merken dat Array.prototype.forEach niet kapot gaat wanneer de callback false retourneert. jQuery en Underscore.js bieden hun eigen variaties op each om lussen te bieden die kunnen worden kortgesloten.


Antwoord 6

Als je een array wilt doorlopen, gebruik dan de standaard driedelige for-lus.

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

Je kunt prestatie-optimalisaties krijgen door myArray.length in de cache te plaatsen of er achteruit te herhalen.


Antwoord 7

Als je het niet erg vindt om de array leeg te maken:

var x;
while(x = y.pop()){ 
    alert(x); //do something 
}

x zal de laatste waarde van y bevatten en zal uit de array worden verwijderd. Je kunt ook shift() gebruiken, waarmee het eerste item van y wordt gegeven en verwijderd.


Antwoord 8

Ik weet dat dit een oud bericht is en er zijn al zoveel goede antwoorden. Voor een beetje meer volledigheid dacht ik dat ik er nog een zou toevoegen met behulp van AngularJS. Dit is natuurlijk alleen van toepassing als je Angular gebruikt, natuurlijk, maar toch zou ik het toch willen zeggen.

angular.forEach heeft 2 argumenten en een optioneel derde argument. Het eerste argument is het object (array) waarover moet worden herhaald, het tweede argument is de iteratorfunctie en het optionele derde argument is de objectcontext (in de lus in feite ‘dit’ genoemd.

Er zijn verschillende manieren om de forEach-lus van angular te gebruiken. De eenvoudigste en waarschijnlijk meest gebruikte is

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

Een andere manier die handig is om items van de ene array naar de andere te kopiëren, is

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

Hoewel u dat niet hoeft te doen, kunt u gewoon het volgende doen en dit is gelijk aan het vorige voorbeeld:

angular.forEach(temp, function(item) {
    temp2.push(item);
});

Er zijn nu voor- en nadelen aan het gebruik van de functie angular.forEach in tegenstelling tot de ingebouwde for-lus met vanillesmaak.

Pluspunten

  • Gemakkelijke leesbaarheid
  • Eenvoudige beschrijfbaarheid
  • Indien beschikbaar, zal angular.forEach de ES5 forEach-lus gebruiken. Nu zal ik tot efficiëntie komen in de cons-sectie, omdat de forEach-lussen veel langzamer zijn dan de for-lussen. Ik vermeld dit als een professional omdat het fijn is om consistent en gestandaardiseerd te zijn.

Beschouw de volgende 2 geneste lussen, die precies hetzelfde doen. Laten we zeggen dat we 2 arrays van objecten hebben en elk object bevat een array van resultaten, die elk een Value eigenschap hebben die een string is (of wat dan ook). En laten we zeggen dat we elk van de resultaten moeten herhalen en als ze gelijk zijn, voer dan een actie uit:

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});
//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

Toegegeven, dit is een heel eenvoudig hypothetisch voorbeeld, maar ik heb triple embedded for-loops geschreven met de tweede benadering en het was erg moeilijk te lezen en te schrijven wat dat betreft.

Nadelen

  • Efficiëntie. angular.forEach en de native forEach zijn trouwens beide zo veel langzamer dan de normale for loop….ongeveer 90% langzamer. Dus voor grote datasets kun je het beste vasthouden aan de native for-lus.
  • Geen ondersteuning voor pauzeren, doorgaan of retourneren. continue wordt feitelijk ondersteund door “ongeluk“, om ga verder in een angular.forEach je plaatst eenvoudig een return; statement in de functie zoals angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); waardoor het uit de functie voor die iteratie blijft. Dit is ook te wijten aan het feit dat de native forEach ook geen pauze of doorgaan ondersteunt.

Ik weet zeker dat er ook verschillende andere voor- en nadelen zijn, en voel je vrij om alles toe te voegen dat je nodig hebt. Ik ben van mening dat, als je efficiëntie nodig hebt, alleen de native for-lus voor je looping-behoeften moet blijven. Maar als je datasets kleiner zijn en een beetje efficiëntie oké is om op te geven in ruil voor leesbaarheid en beschrijfbaarheid, gooi dan zeker een angular.forEach in die stoute jongen.


Antwoord 9

Een forEach implementatie (zie in jsFiddle):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}
var myArray = ['hello','world'];
forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);

Antwoord 10

Vanaf ECMAScript 6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

Antwoord 11

Waarschijnlijk is de for(i = 0; i < array.length; i++)-lus niet de beste keuze. Waarom? Als je dit hebt:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

De methode roept array[0] aan naar array[2]. Ten eerste zal dit eerst verwijzen naar variabelen die je niet eens hebt, ten tweede zou je de variabelen niet in de array hebben, en ten derde zal dit de code vetter maken. Kijk hier, het is wat ik gebruik:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

En als je wilt dat het een functie is, kun je dit doen:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

Als je wilt breken, een beetje meer logica:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

Voorbeeld:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

Het geeft terug:

//Hello
//World
//!!!

Antwoord 12

Er zijn drie implementaties van forEach in jQuery als volgt.

var a = [3,2];
$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3

Antwoord 13

Een gemakkelijke oplossing zou nu zijn om de underscore.js-bibliotheek te gebruiken. Het biedt veel handige tools, zoals each en delegeert de taak automatisch aan de native forEach indien beschikbaar.

Een voorbeeld van CodePen van hoe het werkt is:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

Zie ook


Antwoord 14

Er is geen for each lus in native JavaScript . Je kunt bibliotheken gebruiken om deze functionaliteit te krijgen (ik raad Underscore.js aan), een eenvoudige for in lus.

for (var instance in objects) {
   ...
}

Houd er echter rekening mee dat er redenen kunnen zijn om een ​​nog eenvoudigere for-lus te gebruiken (zie Stack Overflow-vraag Waarom is het gebruik van for in met array-iteratie zo’n slecht idee?)

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}

Antwoord 15

Dit is een iterator voor een NIET-sparse lijst waarbij de index begint bij 0, wat het typische scenario is bij het omgaan met document.getElementsByTagName of document.querySelectorAll)

function each( fn, data ) {
    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');
    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   
    return this;
}
Array.prototype.each = each;  

Voorbeelden van gebruik:

Voorbeeld #1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

Voorbeeld #2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Elke p-tag krijgt class="blue"

Voorbeeld #3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Elke andere p-tag krijgt class="red">

Voorbeeld #4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

En tot slot worden de eerste 20 blauwe p-tags gewijzigd in groen

Let op bij het gebruik van string als functie: de functie is buiten de context gemaakt en zou alleen moeten worden gebruikt als je zeker bent van het bereik van variabelen. Anders is het beter om functies door te geven waar scoping intuïtiever is.


Antwoord 16

Er zijn een paar manieren om een ​​array in JavaScript te doorlopen, zoals hieronder:

voor – het is de meest voorkomende. Volledig codeblok voor looping

var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Antwoord 17

ECMAScript 5 (de versie op JavaScript) om met arrays te werken:

forEach – doorloopt elk item in de array en doet met elk item wat u maar wilt.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is #" + (index+1) + " in the musical scale");
});
// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

In het geval dat u meer geïnteresseerd bent in bewerking op array met behulp van een ingebouwde functie.

map – Het creëert een nieuwe array met het resultaat van de callback-functie. Deze methode is goed om te gebruiken wanneer u de elementen van uw array moet opmaken.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});
// Output: ['BOB', 'JOE', 'JEN']

reduce – Zoals de naam al zegt, reduceert het de array tot een enkele waarde door de gegeven functie aan te roepen die het huidige element en het resultaat van de vorige uitvoering doorgeeft.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every – Retourneert waar of onwaar als alle elementen in de array de test in de callback-functie doorstaan.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];
ages.every(function(elem) {
  return elem >= 18;
});
// Output: false

filter – Zeer vergelijkbaar met elke, behalve dat filter een array retourneert met de elementen die true retourneren aan de gegeven functie.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});
// Output: [2,4,6]

Antwoord 18

Er is geen ingebouwde mogelijkheid om forEach in te breken. Om de uitvoering te onderbreken, gebruikt u de Array#some zoals hieronder:

[1,2,3].some(function(number) {
    return number === 1;
});

Dit werkt omdat some true retourneert zodra een van de callbacks, uitgevoerd in arrayvolgorde, true retourneert, waardoor de uitvoering van de rest wordt kortgesloten.
Origineel antwoord
zie Array-prototype voor sommige


Antwoord 19

Ik zou dit ook willen toevoegen als een compositie van een omgekeerde lus en een antwoord hierboven voor iemand die deze syntaxis ook zou willen.

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

Voors:

Het voordeel hiervan: je hebt de referentie al in de eerste, zodat je later niet met een andere regel hoeft te worden aangegeven. Het is handig bij het doorlopen van de objectarray.

Nadelen:

Dit wordt verbroken wanneer de verwijzing onwaar is – onwaar (niet gedefinieerd, enz.). Het kan echter als een voordeel worden gebruikt. Het zou het lezen echter wat moeilijker maken. En ook afhankelijk van de browser kan het “niet” worden geoptimaliseerd om sneller te werken dan de originele.


Antwoord 20

jQuery-manier met $.map:

var data = [1, 2, 3, 4, 5, 6, 7];
var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});
// newData = [2, 4, 6];

Antwoord 21

Lussen gebruiken met ECMAScript 6 destructuring en de spread-operator

Destructurering en het gebruik van de spread-operator is voor nieuwkomers in ECMAScript 6 behoorlijk nuttig gebleken omdat het voor mensen leesbaarder/esthetischer is, hoewel sommige JavaScript-veteranen het misschien rommelig vinden. Junioren of andere mensen vinden het misschien handig.

De volgende voorbeelden gebruiken de for...of-instructie en de .forEach methode.

Voorbeelden 6, 7 en 8 kunnen worden gebruikt met alle functionele lussen zoals .map, .filter, .reduce, .sort, .every, .some. Bekijk voor meer informatie over deze methoden het Array Object.

Voorbeeld 1: Normale for...of lus – geen trucjes hier.

let arrSimple = ['a', 'b', 'c'];
for (let letter of arrSimple) {
  console.log(letter);
}

Antwoord 22

Een manier die het dichtst bij uw idee komt, is om Array.forEach() te gebruiken, die een sluitingsfunctie accepteert die voor elk element van de array wordt uitgevoerd.

myArray.forEach(
  (item) => {
    // Do something
    console.log(item);
  }
);

Een andere haalbare manier zou zijn om Array.map() te gebruiken, dat op dezelfde manier werkt, maar het neemt ook alle waarden die u retourneert en retourneert ze in een nieuwe array (in wezen in kaart brengend elk element naar een nieuwe), als volgt:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);
console.log(myArray); // [2, 3, 4]

Antwoord 23

Prestaties

Vandaag (2019-12-18) voer ik een test uit op mijn macOS v10.13.6 (High Sierra), op Chrome v 79.0, Safari v13.0.4 en Firefox v71.0 (64 bit) – conclusies over optimalisatie (en micro-optimization wat meestal niet de moeite waard is om het in code te introduceren omdat het voordeel klein is, maar de codecomplexiteit groeit).

  • Het lijkt erop dat de traditionele for i (Aa) een goede keuze is om snelle code in alle browsers te schrijven.

  • De andere oplossingen, zoals for-of (Advertentie), allemaal in groep C.… zijn meestal 2 – 10 (en meer) keer langzamer dan Aa, maar voor kleine arrays is het oké om het te gebruiken – omwille van de duidelijkheid van de code.

  • De lussen met array-lengte in de cache in n (Ab, Bb, Be) zijn soms sneller, soms niet. Waarschijnlijk detecteren compilers deze situatie automatisch en introduceren ze caching. De snelheidsverschillen tussen de gecachte en niet-gecachete versies (Aa, Ba, Bd) zijn ongeveer ~1%, dus het lijkt erop dat introduce n een micro-optimalisatie.

  • De i---achtige oplossingen waarbij de lus begint vanaf het laatste array-element (Ac, Bc) zijn meestal ~30% langzamer dan voorwaartse oplossingen – waarschijnlijk is de reden de manier van CPU-geheugencache werkt – voorwaarts lezen van geheugen is meer optimaal voor CPU-caching). Het wordt aanbevolen om dergelijke oplossingen NIET TE GEBRUIKEN.

Details

In tests berekenen we de som van array-elementen. Ik voer een test uit voor kleine arrays (10 elementen) en grote arrays (1M elementen) en verdeel ze in drie groepen:

  • Afor tests
  • Bwhile tests
  • C – andere/alternatieve methoden
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
//let arr = Array.from(Array(1000000), (x, i) => i%10);
function Aa(a, s=0) {
  for(let i=0; i<a.length; i++) {
    s += a[i];
  }
  console.log('Aa=', s);
}
function Ab(a, s=0) {
  let n = a.length;
  for(let i=0; i<n; i++) {
    s += a[i];
  }
  console.log('Ab=', s);
}
function Ac(a, s=0) {
  for(let i=a.length; i--;) {
    s += a[i];
  }
  console.log('Ac=', s);
}
function Ad(a, s=0) {
  for(let x of a) {
    s += x;
  }
  console.log('Ad=', s);
}
function Ae(a, s=0) {
  for(let i in a) if (a.hasOwnProperty(i)) {
    s += a[i];
  }
  console.log('Ae=', s);
}
function Ba(a, s=0) {
  let i = -1;
  while(++i < a.length) {
    s+= a[i];
  }
  console.log('Ba=', s);
}
function Bb(a, s=0) {
  let i = -1;
  let n = a.length;
  while(++i < n) {
    s+= a[i];
  }
  console.log('Bb=', s);
}
function Bc(a, s=0) {
  let i = a.length;
  while(i--) {
    s += a[i];
  }
  console.log('Bc=', s);
}
function Bd(a, s=0) {
  let i = 0;
  do {
    s+= a[i]
  } while (++i < a.length);
  console.log('Bd=', s);
}
function Be(a, s=0) {
  let i = 0;
  let n = a.length;
  do {
    s += a[i]
  } while (++i < n);
  console.log('Be=', s);
}
function Bf(a, s=0) {
  const it = a.values(); 
  let e;
  while (!(e = it.next()).done) { 
    s+= e.value; 
  }
  console.log('Bf=', s);
}
function Ca(a, s=0) {
  a.map(x => { s+=x });
  console.log('Ca=', s);
}
function Cb(a, s=0) {
  a.forEach(x => { s+=x });
  console.log('Cb=', s);
}
function Cc(a, s=0) {
  a.every(x => (s += x, 1));
  console.log('Cc=', s);
}
function Cd(a, s=0) {
  a.filter(x => { s+=x });
  console.log('Cd=',s);
}
function Ce(a, s=0) {
  a.reduce((z, c) => { s+=c }, 0);
  console.log('Ce=', s);
}
function Cf(a, s=0) {
  a.reduceRight((z, c) => { s += c }, 0);
  console.log('Cf=', s);
}
function Cg(a, s=0) {
  a.some(x => { s += x } );
  console.log('Cg=', s);
}
function Ch(a, s=0) {
  Array.from(a, x=> s += x);
  console.log('Cc=', s);
}
Aa(arr);
Ab(arr);
Ac(arr);
Ad(arr);
Ae(arr);
Ba(arr);
Bb(arr);
Bc(arr);
Bd(arr);
Be(arr);
Bf(arr);
Ca(arr);
Cb(arr);
Cc(arr);
Cd(arr);
Ce(arr);
Cf(arr);
Cg(arr);
Ch(arr);
<p style="color: red">This snippets only PRESENTS code used for benchmark - it not perform test itself</p>

Antwoord 24

De lambda-syntaxis werkt meestal niet in Internet Explorer 10 of lager.

Ik gebruik meestal de

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

Als je een jQuery fan bent en al een jQuery-bestand draait, moet je de posities van de index- en waardeparameters omkeren

$("#ul>li").each(function(**index, value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

Antwoord 25

U kunt voor elk zo bellen:

forEach herhaalt de array die u opgeeft en voor elke iteratie heeft het element dat de waarde van die iteratie bevat. Als je index nodig hebt, kun je de huidige index krijgen door de i door te geven als de tweede parameter in de callback-functie voor forEach.

Foreach is in feite een functie van hoge orde, die een andere functie als parameter heeft.

let theArray= [1,3,2];
theArray.forEach((element) => {
  // Use the element of the array
  console.log(element)
}

Uitvoer:

1
3
2

Je kunt ook een array als volgt herhalen:

for (let i=0; i<theArray.length; i++) {
  console.log(i); // i will have the value of each index
}

Antwoord 26

Als je forEach() wilt gebruiken, ziet het er als volgt uit –

theArray.forEach ( element => {
    console.log(element);
});

Als je for() wilt gebruiken, ziet het er als volgt uit –

for(let idx = 0; idx < theArray.length; idx++){
    let element = theArray[idx];
    console.log(element);
}

Antwoord 27

Als u een reeks objecten wilt doorlopen met de pijlfunctie:

let arr = [{name:'john', age:50}, {name:'clark', age:19}, {name:'mohan', age:26}];
arr.forEach((person)=>{
  console.log('I am ' + person.name + ' and I am ' + person.age + ' old');
})

Antwoord 28

Volgens de nieuwe bijgewerkte functie ECMAScript 6 (ES6) en ECMAScript 2015, kunt u de volgende opties gebruiken met loops:

voor loops

for(var i = 0; i < 5; i++){
  console.log(i);
}
// Output: 0,1,2,3,4

voor…in loops

let obj = {"a":1, "b":2}
for(let k in obj){
  console.log(k)
}
// Output: a,b

Array.forEach()

let array = [1,2,3,4]
array.forEach((x) => {
  console.log(x);
})
// Output: 1,2,3,4

voor…van loops

let array = [1,2,3,4]
for(let x of array){
  console.log(x);
}
// Output: 1,2,3,4

terwijl-loops

let x = 0
while(x < 5){
  console.log(x)
  x++
}
// Output: 1,2,3,4

do…while-loops

let x = 0
do{
  console.log(x)
  x++
}while(x < 5)
// Output: 1,2,3,4

Antwoord 29

Samenvatting:

Als we een array herhalen, willen we vaak een van de volgende doelen bereiken:

  1. We willen de array herhalen en een nieuwe array maken:

    Array.prototype.map

  2. We willen de array herhalen en geen nieuwe array maken:

    Array.prototype.forEach

    for..of loop

In JavaScript zijn er veel manieren om beide doelen te bereiken. Sommige zijn echter handiger dan andere. Hieronder vindt u enkele veelgebruikte methoden (de handigste IMO) om array-iteratie in JavaScript uit te voeren.

Nieuwe array maken: map

map() is een functie op Array.prototype die elk element van een array kan transformeren en vervolgens een nieuwe array retourneert. map() neemt als argument een callback-functie en werkt op de volgende manier:

let arr = [1, 2, 3, 4, 5];
let newArr = arr.map((element, index, array) => {
  return element * 2;
})
console.log(arr);
console.log(newArr);

Antwoord 30

Als je een enorme array hebt, moet je gebruiken iterators om wat efficiëntie te bereiken. Iterators zijn eigendom van bepaalde JavaScript-verzamelingen (zoals Map, Set, String, Array). Zelfs, for..of gebruikt iterator onder de motorkap.

Iterators verbeteren de efficiëntie door u de items in een lijst één voor één te laten consumeren alsof het een stream is. Wat een iterator speciaal maakt, is hoe hij een verzameling doorkruist. Andere lussen moeten de hele verzameling van tevoren laden om eroverheen te itereren, terwijl een iterator alleen de huidige positie in de verzameling hoeft te kennen.

Je krijgt toegang tot het huidige item door de next methode van de iterator aan te roepen. De volgende methode retourneert de value van het huidige item en een boolean om aan te geven wanneer je het einde hebt bereikt van de collectie. Het volgende is een voorbeeld van het maken van een iterator van een array.

Transform uw normale array naar iterator met behulp van values() methode als volgt:

    const myArr = [2,3,4]
let it = myArr.values();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes