For..In boucles en JavaScript - paires de valeurs clés

414

Je me demandais s'il y avait un moyen de faire quelque chose comme une foreachboucle PHP en JavaScript. La fonctionnalité que je recherche est quelque chose comme cet extrait PHP:

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

Je regardais la for..inboucle JS , mais il semble qu'il n'y ait aucun moyen de spécifier le as. Si je le fais avec une boucle normale pour loop ( for(var i = 0; i < data.length; i++), existe-t-il un moyen de saisir les paires clé => valeur?

cabaret
la source

Réponses:

217

Si vous pouvez utiliser ES6 en mode natif ou avec Babel (compilateur js), vous pouvez effectuer les opérations suivantes:

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

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

Qui imprimera cette sortie:

a 1
b 2
c 3

La Object.entries()méthode retourne un tableau des propres [key, value]paires de propriétés énumérables d'un objet donné , dans le même ordre que celui fourni par une for...inboucle (la différence étant qu'une boucle for-in énumère également les propriétés de la chaîne de prototype) .

J'espère que cela aide! =)

Francesco Casula
la source
1
Cela fonctionne parfaitement, je me demande simplement - par rapport à "pour saisir un objet puis obtenir la valeur par objet [clé]", lequel donne de meilleures performances?
lsheng
1
Dans ce cas précis, je suppose que c'est plus lent à cause de l' Object.entriesappel. Je n'ai cependant effectué aucun test.
Francesco Casula
6
c'est la meilleure réponse à la question posée, qui demandait de saisir la clé et la valeur dans la boucle for.
cipak
4
La réponse acceptée doit être mise à jour car elle répond en fait à la question, bien qu'elle ne soit pas disponible au moment de la question.
Marc Qualie
1
Vous voudrez peut-être vérifier cette question: stackoverflow.com/questions/47213651/… qui semble indiquer qu'une syntaxe de ce type serait recommandée: Object.keys (myObject) .forEach (key => {...
Will59
519
for (var k in target){
    if (target.hasOwnProperty(k)) {
         alert("Key is " + k + ", value is " + target[k]);
    }
}

hasOwnPropertyest utilisé pour vérifier si vous avez targetvraiment cette propriété, plutôt que de l'avoir héritée de son prototype. Un peu plus simple serait:

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

Il vérifie seulement que kn'est pas une méthode (comme si targetest arrayvous obtenez beaucoup de méthodes alerté, par exemple indexOf, push, pop, etc.)

J0HN
la source
87
Une autre façon d'itérer uniquement sur les propriétés "propres" est Object.keys. Object.keys(target).forEach(function (key) { target[key]; });.
katspaugh
3
ne fonctionnera pas si targetest créé en utilisant Object.create(null), le code doit être changé target.hasOwnProperty(k)->Object.prototype.hasOwnProperty.call(target,k)
Azder
pourquoi ne pas utiliser les variables données dans l'exemple de question? Qu'est-ce que c'est k, targetet property? Pour moi, non-javascripter cette zone indéfinie :)
Gediminas
2
Object.keys (cible) .forEach ((clé) => {cible [clé];}); pour Angular
askilondz
315

Personne n'a mentionné, Object.keysdonc je vais le mentionner.

Object.keys(obj).forEach(function (key) {
   // do something with obj[key]
});
chèvre
la source
3
Remarque: non pris en charge par IE8 et versions antérieures.
Edwin Stoteler
1
À ce stade, vous devez utiliser une cale ES5. Si vous vivez dans un bel avenir for of ES6,
goatslacker
17
Il convient de noter que "Il n'y a aucun moyen d'arrêter ou de rompre une boucle forEach () autrement qu'en lançant une exception"
rluks
Object.keys (obj) .forEach ((key) => {}); pour Angular
askilondz
Cela ne fonctionne pas sur ES6 ou je ne le comprends pas. Felix a une réponse meilleure et plus lisible ci-dessous: data.forEach (fonction (valeur, index) {console.log (index); // 0, 1, 2 ...});
gtamborero
115

car ... en travaillera pour vous.

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

En JavaScript moderne, vous pouvez également faire ceci:

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

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

}

La syntaxe php est juste du sucre.

Zirak
la source
Cela itérera également sur toutes les propriétés héritées. Pour éviter cela, utilisez .hasOwnProperty ().
LSerni
24

Je suppose que vous savez que ic'est la clé et que vous pouvez obtenir la valeur via data[i](et que vous voulez juste un raccourci pour cela).

ECMAScript5 a introduit forEach [MDN] pour les tableaux (il semble que vous ayez un tableau):

data.forEach(function(value, index) {

});

La documentation MDN fournit une cale pour les navigateurs qui ne la prennent pas en charge.

Bien sûr, cela ne fonctionne pas pour les objets, mais vous pouvez créer une fonction similaire pour eux:

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

Depuis que vous avez marqué la question avec , jQuery fournit $.each [docs] qui fait une boucle sur les structures de tableau et d'objet.

Felix Kling
la source
C'est Array forEach, pas objet forEach.
2
Donc? Apparemment, l'OP est en boucle sur un tableau.
Felix Kling
Mozilla (Firefox, SpiderMonkey-C, Rhino & c) a également une extension non standard qui permet la for eachsyntaxe. for each (let val in myObj) console.log(val);.
katspaugh
2
@katspaugh: D'accord, mais comme c'est uniquement Mozilla, cela ne semble pas être très utile.
Felix Kling
Merci beaucoup pour votre réponse. Je vais relire les informations que vous avez fournies. Votre hypothèse au début de la réponse était juste, je le savais, sauf que je me suis tellement mis dans la tête avec ce projet que je ne peux pas me concentrer et l'oublier .. Merci.
cabaret du
10

Vous pouvez utiliser le for..inpour cela.

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

En javascript, chaque objet a un tas de paires clé-valeur intégrées qui ont des méta-informations. Lorsque vous parcourez toutes les paires clé-valeur pour un objet, vous les parcourez également. L'utilisation de hasOwnProperty () les filtre.

Siddhu
la source
2

ES6 fournira Map.prototype.forEach (rappel) qui peut être utilisé comme ceci

myMap.forEach(function(value, key, myMap) {
                        // Do something
                    });
Stephen Murby
la source
2
quel est le paramètre myMap?
phil294
Une carte n'est pas un objet. Ce sont des choses complètement distinctes.
Dakusan
2
La fonction forEach ne contient pas la «clé» du tableau mais plutôt l'index de l'élément que vous êtes en train d'itérer.
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
吴毅 凡
la source
5
Vous pouvez ajouter une explication avec le code que vous avez publié au lieu de publier un code simple qui pourrait ne pas être compréhensible.
AaoIi
Object.entries sort un tableau de tableaux sur la base des paires clé / valeur de l'objet d' origine: [['a', 1],['b',2],['c',3]]. Le forEachdéconstruit chacun des tableaux clé / valeur et définit les deux variables sur keyet value, à utiliser comme vous le souhaitez pour la fonction in - ici sortie dans console.log.
Mark Swardstrom
1

Vous pouvez utiliser une boucle 'for in' pour cela:

for (var key in bar) {
     var value = bar[key];
}
Richard Dalton
la source
1

Voici un exemple qui se rapproche le plus possible.

for(var key in data){
  var value = data[key];    
  //your processing here
}

Si vous utilisez jQuery, voir: http://api.jquery.com/jQuery.each/

Aidamina
la source
1

Si vous utilisez Lodash , vous pouvez utiliser_.forEach

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

Au cours des dernières années depuis que cette question a été posée, Javascript a ajouté quelques nouvelles fonctionnalités. L'un d'eux est la méthode Object.Entries .

Copié directement à partir de MDN est l'extrait de code suivant


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

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

oui, vous pouvez également avoir des tableaux associatifs en 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 ...
}
Alex Pacurar
la source
@PaulPRO ... tout en javascript est une paire clé-valeur (ainsi, un objet est en fait un tableau associatif de paires clé-valeur ...)
Alex Pacurar
@AlexPacurar et tableau associatif a un ordre. Un objet n'est pas ordonné. c'est une grande différence
Raynos
@Raynos vous avez peut-être raison ... ce sera d'une grande aide pour expliquer exactement comment un objet n'est pas ordonné ... étant donné l'exemple ci-dessus, on pourrait s'attendre à ce que le "i" dans la boucle for soit [nom, autre Propriété, et enfin dater] ... alors dans quelle situation l'ordre des propriétés d'un objet sera-t-il mélangé?
Alex Pacurar
@AlexPacurar l'ordre particulier dans lequel il va boucler sur l'objet est spécifique au navigateur. Certains le font par ordre alphabétique, certains le font par ordre de définition, etc.
Raynos
3
@Raynos: Les tableaux associatifs sont-ils nécessairement ordonnés? J'ai souvent vu le terme utilisé plus généralement. Par exemple, dans l'article Wikipedia du tableau associatif .
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;
user278064
la source