Disons que nous avons un tableau d'objets comme:

var fruits = [ {name:"banana", weight:150},{name:"apple", weight:95},{name:"orange", weight:160},{name:"kiwi", weight:80} ];

Je veux remplir un tableau "heavy_fruits" avec des éléments du tableau "fruits" au-dessus desquels le poids est> 100. Voici mon code:

var heavy_fruits = [];
myfruit = {};

fruits.forEach(function(item,index) {
  if ( item.weight > 100 ) { 
    myfruit ["name"] = item.name;
    myfruit ["weight"] = item.weight;
  }

heavy_fruits.push(myfruit);
});

Cependant il montre: nom: "orange", poids: 160 nom: "orange", poids: 160 nom: "orange", poids: 160 nom: "orange", poids: 160

Je sais que c'est un problème avec le mélange des fermetures et des boucles ... mais j'ai lu un article (http://zsoltfabok.com/blog/2012/08/javascript-foreach/) expliquant que j'éviterais ce genre de problème en utilisant une boucle forEach au lieu de la boucle for classique.

Je sais que je peux utiliser des méthodes de tableau comme filter (), etc. mais je le demande exprès car j'ai des problèmes avec une fonction beaucoup plus grande que je ne peux pas exposer ici ... J'ai donc essayé de résumer et de simplifier mon description de l'émission avec "fruits".

3
nadir 9 août 2016 à 18:52

3 réponses

Meilleure réponse
var heavy_fruits = [];
myfruit = {}; // here's your object

fruits.forEach(function(item,index) {
    if ( item.weight > 100 ) { 
        myfruit ["name"] = item.name;
        myfruit ["weight"] = item.weight; // you modify it's properties
    }

    heavy_fruits.push(myfruit); // you push it to the array
});

Vous vous retrouvez avec un tableau [myfruit, myfruit, myfruit, myfruit].

Maintenant, si vous modifiez myfruit n'importe où dans le code, le changement sera visible dans chaque occurrence unique de myfruit. Pourquoi?

Parce que vous modifiez la référence à l'objet. Dans cet exemple, votre tableau ne stocke que des copies de votre objet. Et si vous en changez une, chacune changera, car ce sont toutes des références.

Pour résoudre ce problème à chaque itération, vous devez créer un nouvel objet, puis faire des choses dessus.

BTW, en fait, votre if pourrait simplement être comme ceci:

if ( item.weight > 100 ) { 
    heavy_fruits.push(item); // if `item` only has `name` and `weight` properties
}
2
Adrian Wydmanski 9 août 2016 à 16:09
 fruits.forEach(function (item, index) {
  if (item.weight > 100) {
    myfruit = {};
    myfruit["name"] = item.name;
    myfruit["weight"] = item.weight;
    heavy_fruits.push(myfruit);
  }
}); 
1
Gangz 9 août 2016 à 16:03

Le plus court utiliserait un filtre

var heavy_fruits = fruits.filter(x => x.weight > 100);

Mais si vous voulez vraiment utiliser forEach, faites de cette façon

var heavy_fruits = [];
fruits.forEach(x => {if(x.weight > 100) heavy_fruits.push(x)} );
0
kevin ternet 9 août 2016 à 16:10