For..In loop in JavaScript - coppie chiave-valore


414

Mi chiedevo se c'è un modo per fare qualcosa come un foreachciclo PHP in JavaScript. La funzionalità che sto cercando è qualcosa di simile a questo frammento di PHP:

foreach($data as $key => $value) { }

Stavo guardando il for..inloop JS , ma non sembra esserci modo di specificare il as. Se lo faccio con un 'normale' per loop ( for(var i = 0; i < data.length; i++), c'è un modo per afferrare le coppie chiave => valore?

Risposte:


216

Se è possibile utilizzare ES6 in modo nativo o con Babel (compilatore js), è possibile effettuare le seguenti operazioni:

const test = {a: 1, b: 2, c: 3};

for (const [key, value] of Object.entries(test)) {
  console.log(key, value);
}

Che stamperà questo output:

a 1
b 2
c 3

Il Object.entries()metodo restituisce una matrice delle [key, value]coppie di proprietà enumerabili di un determinato oggetto , nello stesso ordine di quello fornito da un for...inciclo (la differenza è che un ciclo for-in elenca anche le proprietà nella catena di prototipi) .

Spero che sia d'aiuto! =)


1
Funziona perfettamente, solo chiedendosi - rispetto a "per chiave nell'oggetto e quindi ottenere valore per oggetto [chiave]", quale offre prestazioni migliori?
lsheng

1
In questo caso specifico, suppongo che sia più lento a causa della Object.entrieschiamata. Tuttavia non ho eseguito alcun test.
Francesco Casula,

6
questa è la migliore risposta alla domanda attuale, che ha chiesto di afferrare sia la chiave che il valore nel ciclo for.
cipak

4
La risposta accettata dovrebbe essere aggiornata poiché in realtà risponde alla domanda, sebbene non fosse disponibile al momento della domanda.
Marc Qualie,

1
Potresti voler controllare questa domanda: stackoverflow.com/questions/47213651/… che sembra indicare che sarebbe consigliata una sintassi di questo tipo: Object.keys (myObject) .forEach (key => {...
Will59

519
for (var k in target){
    if (target.hasOwnProperty(k)) {
         alert("Key is " + k + ", value is " + target[k]);
    }
}

hasOwnPropertyviene utilizzato per verificare se la tua targetproprietà è davvero tale, anziché averla ereditata dal suo prototipo. Un po 'più semplice sarebbe:

for (var k in target){
    if (typeof target[k] !== 'function') {
         alert("Key is " + k + ", value is" + target[k]);
    }
}

E 'solo i controlli che knon è un metodo (come se targetè arraysi otterrà un sacco di metodi allertato, ad esempio indexOf, push, pop, ecc.)


87
Un altro modo per ripetere solo le proprietà "proprie" è Object.keys. Object.keys(target).forEach(function (key) { target[key]; });.
katspaugh,

3
non funzionerà se targetviene creato utilizzando Object.create(null), il codice deve essere modificato target.hasOwnProperty(k)->Object.prototype.hasOwnProperty.call(target,k)
Azder

perché non usare le variabili fornite nell'esempio della domanda? Ciò che qui è k, targete property? Per me, non javascripter, quest'area indefinita :)
Gediminas,

2
Object.keys (target) .forEach ((key) => {target [key];}); per Angular
askilondz,

315

Nessuno ha menzionato, Object.keysquindi lo menzionerò.

Object.keys(obj).forEach(function (key) {
   // do something with obj[key]
});

3
Nota: non supportato da IE8 e precedenti.
Edwin Stoteler,

1
A questo punto dovresti usare uno spessore ES5. Se vivi nel bel futuro ES6 usa for of tc39wiki.calculist.org/es6/for-of
goatslacker l'

17
Vale la pena notare che "Non c'è modo di interrompere o interrompere un ciclo forEach () se non lanciando un'eccezione"
rluks

Object.keys (obj) .forEach ((key) => {}); per Angular
askilondz,

Non funziona su ES6 o non lo capisco. Felix ha una risposta migliore e più leggibile di seguito: data.forEach (funzione (valore, indice) {console.log (indice); // 0, 1, 2 ...});
gtamborero,

115

per ... in funzionerà per te.

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

Nel moderno JavaScript puoi anche fare questo:

for ( const [key,value] of Object.entries( obj ) ) {

}

64
var obj = {...};
for (var key in obj) {
    var value = obj[key];

}

La sintassi php è solo zucchero.


Questo ripeterà anche su tutte le proprietà ereditate. Per evitare ciò, usa .hasOwnProperty ().
LSerni,

24

Suppongo che tu sappia che iè la chiave e che puoi ottenere il valore tramite data[i](e vuoi solo una scorciatoia per questo).

ECMAScript5 ha introdotto forEach [MDN] per gli array (sembra che tu abbia un array):

data.forEach(function(value, index) {

});

La documentazione MDN fornisce uno shim per i browser che non la supportano.

Ovviamente questo non funziona per gli oggetti, ma è possibile creare una funzione simile per loro:

function forEach(object, callback) {
    for(var prop in object) {
        if(object.hasOwnProperty(prop)) {
            callback(prop, object[prop]);
        }
    }
}

Dal momento che hai taggato la domanda con , jQuery fornisce $.each [documenti] che scorre su entrambe le strutture di array e oggetti.


Questa è matrice forEach, non oggetto forEach.

2
Così? Apparentemente l'OP sta eseguendo il looping su un array.
Felix Kling,

Anche Mozilla (Firefox, SpiderMonkey-C, Rhino ecc.) Ha un'estensione non standard che consente la for eachsintassi. for each (let val in myObj) console.log(val);.
katspaugh,

2
@katspaugh: Giusto, ma dato che è solo Mozilla, non sembra essere molto utile.
Felix Kling,

Grazie mille per la tua risposta. Leggerò le informazioni che hai fornito. Il tuo presupposto all'inizio della risposta era giusto, lo sapevo, tranne per il fatto che ho avuto così tanto in testa con questo progetto che non riesco a concentrarmi e non me ne sono dimenticato. Grazie.
cabaret,


9
for (var key in myMap) {
    if (myMap.hasOwnProperty(key)) {
        console.log("key =" + key);
        console.log("value =" + myMap[key]);
    }
}

In JavaScript, ogni oggetto ha un mucchio di coppie chiave-valore integrate che hanno meta-informazioni. Quando esegui il ciclo attraverso tutte le coppie chiave-valore per un oggetto, esegui anche il ciclo. L'uso di hasOwnProperty () li filtra.


2

ES6 fornirà Map.prototype.forEach (callback) che può essere utilizzato in questo modo

myMap.forEach(function(value, key, myMap) {
                        // Do something
                    });

2
qual è il parametro myMapper?
phil294

Una mappa non è un oggetto. Sono cose completamente separate.
Dakusan,

2
La funzione forEach non contiene la 'chiave' dell'array ma più l'indice dell'elemento che stai ripetendo.
Francis Malloch,

2
let test = {a: 1, b: 2, c: 3};
Object.entries(test).forEach(([key, value]) => console.log(key, value))

// a 1
// b 2
// c 3

5
Puoi aggiungere alcune spiegazioni con il codice che hai pubblicato invece di pubblicare un codice semplice che potrebbe non essere comprensibile.
AaoIi,

Object.entries estrae una matrice di matrici basate sulle coppie chiave / valore dell'oggetto originale: [['a', 1],['b',2],['c',3]]. La forEachdecostruisce ciascuno dei chiave / valore array e imposta le due variabili a keye value, da utilizzare come si desidera che la funzione - qui in uscita console.log.
Mark Swardstrom,

1

Puoi usare un ciclo 'for in' per questo:

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


1

Se stai usando Lodash , puoi usare_.forEach

_.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
  console.log(key + ": " + value);
});
// => Logs 'a: 1' then 'b: 2' (iteration order is not guaranteed).

1

Negli ultimi anni da quando è stata posta questa domanda, Javascript ha aggiunto alcune nuove funzionalità. Uno di questi è il metodo Object.Entries .

Copiato direttamente da MDN è lo snippet di codice seguente


const object1 = {
  a: 'somestring',
  b: 42
};

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}

-2

si, puoi avere array associativi anche in javascript:

var obj = 
{
    name:'some name',
    otherProperty:'prop value',
    date: new Date()
};
for(i in obj)
{
    var propVal = obj[i]; // i is the key, and obj[i] is the value ...
}

@PaulPRO ... tutto in javascript è una coppia chiave-valore (quindi un oggetto è in realtà un array associativo di coppie chiave-valore ...)
Alex Pacurar,

@AlexPacurar e l'array associativo hanno un ordine. Un oggetto non è ordinato. questa è una grande differenza
Raynos

@Raynos potresti avere ragione ... sarà di grande aiuto spiegare esattamente come un oggetto non è ordinato ... dato l'esempio sopra, ci si aspetterebbe che la "i" nel ciclo for sia [name, otherProperty, e infine la data] ... quindi in quale situazione verrà mescolato l'ordine delle proprietà di un oggetto?
Alex Pacurar,

@AlexPacurar l'ordine particolare in cui verrà eseguito il ciclo sull'oggetto è specifico del browser. Alcuni lo fanno in ordine alfabetico, altri lo fanno in ordine di definizione, ecc.
Raynos,

3
@Raynos: gli array associativi sono necessariamente ordinati? Ho visto spesso il termine usato più in generale. Ad esempio, sull'articolo Wikipedia dell'array Associative .
Jeremy Banks,

-8
var global = (function() {
   return this;
})();

// Pair object, similar to Python

function Pair(key, value) {
    this.key = key;
    this.value = value;

    this.toString = function() {
       return "(" + key + ", " + value + ")";
    };
}

/**
 * as function
 * @param {String} dataName A String holding the name of your pairs list.
 * @return {Array:Pair} The data list filled
 *    with all pair objects.
 */
Object.prototype.as = function(dataName) {
    var value, key, data;
    global[dataName] = data = [];

    for (key in this) {
       if (this.hasOwnProperty(key)) {
          value = this[key];

          (function() {
             var k = key,
                 v = value;

            data.push(new Pair(k, v));
          })();
       }
    }

    return data;
};

var d = {
   'one': 1,
   'two': 2
};

// Loop on your (key, list) pairs in this way
for (var i = 0, max = d.as("data").length; i < max; i += 1) {
   key = data[i].key;
   value = data[i].value;

   console.log("key: " + key + ", value: " + value);
}

// delete data when u've finished with it.
delete data;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.