vuoto - stampare array javascript




Passa attraverso un array in JavaScript (20)

In Java è possibile utilizzare un ciclo for per attraversare gli oggetti in un array come segue:

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

Puoi fare lo stesso in JavaScript?


for (var s of myStringArray) {

(Rispondendo direttamente alla tua domanda: ora puoi!)

La maggior parte delle altre risposte sono corrette, ma non menzionano (come da questo scritto) che ECMA Script 6 2015 sta introducendo un nuovo meccanismo per fare iterazione, il ciclo for..of .

Questa nuova sintassi è il modo più elegante per iterare un array in javascript (a patto che non sia necessario l'indice di iterazione), ma non è ancora ampiamente supportato dai browser.

Attualmente funziona con Firefox 13+, Chrome 37+ e non funziona in modo nativo con altri browser (vedi la compatibilità del browser sotto). Fortunatamente abbiamo compilatori JS (come Babel ) che ci consentono di utilizzare le funzionalità di prossima generazione oggi.

Funziona anche su Node (l'ho testato sulla versione 0.12.0).

Iterazione di un array

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

Iterazione di una matrice di oggetti

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

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

Iterazione di un generatore:

(esempio estratto da 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;
  }
}

Tabella di compatibilità: http://kangax.github.io/es5-compat-table/es6/#For..of loops

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

}


Il modo più elegante e veloce

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8

Modificato (perché ho sbagliato)

Confronto tra i metodi per il looping di un array di 100000 elementi e ogni volta un'operazione minima con il nuovo valore.

Preparazione:

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

test:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>

Alcuni casi d'uso del looping attraverso una matrice nel modo di programmazione funzionale in JavaScript:

1. Basta fare un ciclo attraverso un array

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

Nota: Array.prototype.forEach () non è un modo funzionale in senso stretto, poiché la funzione che assume come parametro di input non deve restituire un valore, che quindi non può essere considerato una funzione pura.

2. Verifica se uno qualsiasi degli elementi di un array supera un test

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. Trasforma in un nuovo array

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

Nota: il metodo map () crea una nuova matrice con i risultati della chiamata di una funzione fornita su ogni elemento dell'array chiamante.

4. Riassumi una particolare proprietà e calcola la sua media

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. Creare un nuovo array basato sull'originale ma senza modificarlo

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. Conta il numero di ogni categoria

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. Recupera un sottoinsieme di un array in base a criteri particolari

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

Nota: il metodo filter () crea una nuova matrice con tutti gli elementi che superano il test implementato dalla funzione fornita.

8. Ordina un array

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

9. Trova un elemento in una matrice

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

Il metodo Array.prototype.find () restituisce il valore del primo elemento dell'array che soddisfa la funzione di test fornita.

Riferimenti


C'è un modo per farlo in cui si ha un campo d'azione implicito molto piccolo nel ciclo e si eliminano variabili extra.

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

O se vuoi davvero ottenere l'id e avere un loop davvero classico:

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

I browser moderni supportano tutti i metodi di iteratore forEach , map , reduce , filter e una miriade di altri metodi sul prototipo di Array .


Consiglio vivamente di utilizzare la libreria underscore.js . Fornisce varie funzioni che è possibile utilizzare per iterare su array / raccolte.

Per esempio:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...

Esistono vari modi per eseguire il looping della matrice in JavaScript.

Ciclo generico:

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

ES5's forEach:

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

Dai un'occhiata a this per informazioni dettagliate o puoi anche controllare for...in per il looping attraverso un array in JavaScript e usando jQuery per controllare jQuery.each() .


Opera, Safari, Firefox e Chrome condividono ora una serie di metodi Array avanzati per l'ottimizzazione di molti loop comuni.

Potresti non averne bisogno tutti, ma possono essere molto utili, o lo sarebbero se tutti i browser li supportassero.

Mozilla Labs ha pubblicato gli algoritmi utilizzati da loro e WebKit , in modo che tu possa aggiungerli tu stesso.

filtro restituisce una serie di elementi che soddisfano alcune condizioni o test.

ogni restituisce true se ogni membro dell'array supera il test.

alcuni restituiscono true se qualcuno supera il test.

forEach esegue una funzione su ogni membro dell'array e non restituisce nulla.

la mappa è come perOppure, ma restituisce una matrice dei risultati dell'operazione per ciascun elemento.

Questi metodi hanno tutti una funzione per il loro primo argomento e hanno un secondo argomento opzionale, che è un oggetto il cui ambito si desidera imporre ai membri dell'array mentre passano attraverso la funzione.

Ignoralo finché non ne hai bisogno.

indexOf e lastIndexOf trovano la posizione appropriata del primo o dell'ultimo elemento che corrisponde esattamente al suo argomento.

(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;
})();

Puoi usare la map , che è una tecnica di programmazione funzionale che è disponibile anche in altre lingue come Python e Haskell .

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

La sintassi generale è:

array.map(func)

In generale func richiederebbe un parametro, che è un elemento dell'array. Ma nel caso di JavaScript, può prendere un secondo parametro che è l'indice dell'oggetto e un terzo parametro che è l'array stesso.

Il valore di ritorno di array.map è un altro array, quindi puoi usarlo in questo modo:

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

E ora x è [10,20,30,40] .

Non è necessario scrivere la funzione in linea. Potrebbe essere una funzione separata.

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

new_list = my_list.map(item_processor);

che sarebbe in qualche modo equivalente a:

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

Tranne che non ottieni la new_list .


Sì, ma solo se l'implementazione include il ... of funzionalità introdotte in ECMAScript 2015 (la versione "Harmony").

Funziona così:

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

O meglio ancora, poiché ECMAScript 2015 fornisce anche variabili con scope di blocco tramite let e const :

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

Molti sviluppatori JavaScript stanno ancora lavorando in un ambiente che non c'è ancora, tuttavia, specialmente se si scrive codice per essere eseguito nei browser web, dove gli sviluppatori del sito spesso non sono sicuri di quale browser / versione useranno i propri client.

Se si può supporre che l'interprete JavaScript sia conforme alla precedente edizione della specifica ECMAScript (che esclude, ad esempio, versioni di Internet Explorer precedenti alla 9), è possibile utilizzare il metodo per forEach iteratore invece di un ciclo. In tal caso, si passa una funzione da chiamare su ciascun elemento dell'array:

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

Ma se anche questo è troppo da assumere e vuoi qualcosa che funzioni in tutte le versioni di JavaScript, devi utilizzare un ciclo di conteggio esplicito. La versione più sicura, che gestisce correttamente gli array sparsi, è qualcosa del genere:

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 ...
  }
}

Assegnare il valore della lunghezza alla variabile locale (invece di includere l'espressione myStringArray.length completa nella condizione di loop) può fare una differenza significativa nelle prestazioni poiché ignora ogni volta una ricerca di proprietà; usando Rhino sulla mia macchina, la velocità è del 43%.

Vedrai spesso la cache di lunghezza eseguita nella clausola di inizializzazione del ciclo, come questa:

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

Il for ... in sintassi menzionata da altri è per il looping sulle proprietà di un oggetto; dal momento che una matrice in JavaScript è solo un oggetto con nomi di proprietà numeriche (e una proprietà di length aggiornata automaticamente), è possibile eseguire il loop teorico su una matrice con esso. Ma il problema è che non si limita ai valori delle proprietà numeriche (ricorda che anche i metodi sono in realtà solo proprietà il cui valore è una chiusura), né itera su quelli in ordine numerico. Pertanto, la sintassi for ... in sintassi non deve essere utilizzata per il looping degli array.


Se vuoi un modo teso per scrivere un ciclo veloce e puoi scorrere al contrario:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

Questo ha il vantaggio di memorizzare nella cache la lunghezza (simile a for (var i=0, len=myArray.length; i<len; ++i) e diversamente for (var i=0; i<myArray.length; ++i) ) pur essendo meno caratteri da digitare.

Ci sono persino delle volte in cui dovresti eseguire iterazioni al contrario, ad esempio quando si esegue un'iterazione su un NodeList attivo in cui prevedi di rimuovere elementi dal DOM durante l'iterazione.


Usa un ciclo sequenziale for :

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

@zipcodeman suggerisce l'uso di for...in statement, ma per l'iterazione di array for-in dovrebbe essere evitato, tale istruzione è pensata per enumerare le proprietà dell'oggetto.

Non dovrebbe essere usato per oggetti di tipo array perché:

  • L'ordine di iterazione non è garantito, gli indici di array non possono essere visitati in ordine numerico.
  • Anche le proprietà ereditate sono elencate.

Il secondo punto è che può darti un sacco di problemi, ad esempio, se estendi l'oggetto Array.prototype per includere un metodo, quella proprietà verrà anche enumerata.

Per esempio:

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

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

Il codice sopra avviserà "a", "b", "c" e "foo!".

Questo è particolarmente un problema se si utilizza una libreria che si basa molto sul potenziamento dei prototipi nativi (come ad esempio MooTools).

L'istruzione for-in come ho detto prima è lì per enumerare le proprietà dell'oggetto, ad esempio:

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])
  }
}

Nell'esempio precedente il metodo hasOwnProperty consente di enumerare solo le proprie proprietà , ovvero, solo le proprietà che l'oggetto ha fisicamente, nessuna proprietà ereditata.

Ti consiglierei di leggere il seguente articolo:


Ad esempio, ho usato in una console di Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})

Certo è inefficiente e molti lo disprezzano, ma è uno dei più vicini a quello menzionato:

var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
    // Do something
})

In JavaScript, ci sono così tante soluzioni per il loop di un array.

Il codice qui sotto sono quelli popolari

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()


Non è identico al 100%, ma simile:

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }


Non ho ancora visto questa variazione, che personalmente mi piace di più:

Dato un array:

var someArray = ["some", "example", "array"];

Puoi passarci sopra senza mai accedere alla proprietà length:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

Guarda questo JsFiddle dimostrando che: http://jsfiddle.net/prvzk/

Funziona solo per gli array che non sono sparsi. Significa che in realtà esiste un valore in ciascun indice dell'array. Tuttavia, ho scoperto che in pratica non utilizzo quasi mai array sparsi in Javascript ... In questi casi è solitamente molto più semplice usare un oggetto come mappa / tabella hash. Se si dispone di un array sparse e si desidera eseguire il loop su 0 .. length-1, è necessario il costrutto for (var i = 0; i <someArray.length; ++ i), ma è comunque necessario un se all'interno del loop per verificare se l'elemento nell'indice corrente è effettivamente definito.

Inoltre, come CMS menziona in un commento qui sotto, puoi usarlo solo su array che non contengono valori falsi. La serie di stringhe dell'esempio funziona, ma se hai stringhe vuote o numeri che sono 0 o NaN, ecc. Il ciclo si interromperà prematuramente. Di nuovo, nella pratica, questo non è quasi mai un problema per me, ma è qualcosa da tenere a mente, il che rende questo un ciclo a cui pensare prima di usarlo ... Questo potrebbe squalificarlo per alcune persone :)

Quello che mi piace di questo ciclo è:

  • È breve da scrivere
  • Non è necessario accedere (per non parlare della cache) alla proprietà length
  • L'elemento da accedere viene automaticamente definito all'interno del corpo del ciclo sotto il nome scelto.
  • Combina molto naturalmente con array.push e array.splice per usare matrici come liste / stack

Il motivo per cui questo funziona è che la specifica dell'array richiede che quando si legge un elemento da un indice> = la lunghezza dell'array, esso ritorni indefinito. Quando scrivi in ​​una posizione del genere, in realtà aggiornerà la lunghezza.

Per me, questo costrutto più emula la sintassi di Java 5 che adoro:

for (String item : someArray) {
}

... con l'ulteriore vantaggio di conoscere anche l'indice corrente all'interno del ciclo


Se qualcuno è interessato al lato delle prestazioni dei molteplici meccanismi disponibili per le iterazioni di Array, ho preparato i seguenti test di JSPerf:

https://jsperf.com/fastest-array-iterator

Risultati:

L' for()iteratore tradizionale è di gran lunga il metodo più veloce, specialmente se utilizzato con la lunghezza dell'array memorizzato nella cache .

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // do something
}

L' Array.prototype.forEach()ei Array.prototype.map()metodi sono approssimazioni più lente, probabilmente come conseguenza della chiamata di funzione


Se vuoi usare jQuery, ha un bell'esempio nella sua documentazione:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });

Il modo migliore a mio parere è utilizzare la funzione Array.forEach. Se non è possibile utilizzarlo, suggerirei di ottenere il polyfill da MDN per renderlo disponibile, è sicuramente il modo più sicuro per scorrere su un array in JavaScript.

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Così come altri hanno suggerito, questo è quasi sempre quello che vuoi:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

Ciò garantisce che tutto ciò di cui hai bisogno nell'ambito dell'elaborazione dell'array rimanga all'interno di quell'ambito, e che tu stia elaborando solo i valori dell'array, non le proprietà dell'oggetto e altri membri, che è ciò che per .. in.

utilizzando un normale stile c per loop funziona nella maggior parte dei casi, è solo importante ricordare che tutto ciò che è all'interno del ciclo condivide l'ambito con il resto del programma, il {} non crea un nuovo ambito.

Quindi:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

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

alert(i);

uscirà "11" - che può o non può essere quello che vuoi.

Esempio di lavoro jsFiddle: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/


Se stai usando la libreria jQuery, considera l'utilizzo di http://api.jquery.com/jQuery.each/

Dalla documentazione:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

Restituisce: oggetto

Descrizione: una funzione di iteratore generica, che può essere utilizzata per iterare senza interruzioni su oggetti e array. Le matrici e gli oggetti tipo array con una proprietà length (come l'oggetto arguments di una funzione) sono iterati da un indice numerico, da 0 a length-1. Altri oggetti sono iterati tramite le loro proprietà nominate.

La $.each()funzione non è la stessa di $(selector).each(), che viene utilizzata per iterare, esclusivamente, su un oggetto jQuery. La $.each()funzione può essere utilizzata per iterare su qualsiasi raccolta, indipendentemente dal fatto che si tratti di una mappa (oggetto JavaScript) o di un array. Nel caso di un array, il callback riceve ogni volta un indice di array e un valore di array corrispondente. (Il valore si può accedere anche attraverso la thisparola chiave, ma Javascript sarà sempre avvolgere il thisvalore come Object, anche se si tratta di una semplice stringa o valore numerico.) Il metodo restituisce il primo argomento, l'oggetto che è stato iterato.





for-loop