Est-il une différence entre foreach et de la carte?

Ok C'est plus une question informatique qu'une question basée sur un langage particulier, mais y a-t-il une différence entre une opération map et une opération foreach? Ou sont-ils simplement des noms différents pour la même chose?

200
demandé sur hippietrail 2008-12-10 05:09:29

8 réponses

Différent.

Foreach itère sur une liste et applique une opération avec des effets secondaires à chaque membre de la liste (comme l'enregistrement de chacun dans la base de données par exemple)

Map itère sur une liste, transforme chaque membre de cette liste et renvoie une autre liste de la même taille avec les membres transformés (comme la conversion d'une liste de chaînes en majuscules)

277
répondu madlep 2008-12-10 02:14:53

La différence importante entre eux est que map accumule tous les résultats dans une collection, alors que foreach ne renvoie rien. map est généralement utilisé lorsque vous souhaitez transformer une collection d'éléments avec une fonction, alors que foreach exécute simplement une action pour chaque élément.

111
répondu Henk 2008-12-10 02:15:31

Bref, foreach est pour appliquer une opération sur chaque élément d'une collection d'éléments, alors que map est la transformation d'une collection à une autre.

Il existe deux différences significatives entre foreach et map.

  1. foreach n'a pas de restrictions conceptuelles sur l'opération qu'il applique, sauf peut-être accepter un élément comme argument. Qui est, l'opération peut ne rien faire, peut avoir un effet secondaire peut retourner une valeur ou ne peut pas retourner une valeur. Tous foreach se soucie est d'itérer sur une collection d'éléments, et d'appliquer l'opération sur chaque élément.

    map, d'un autre côté, a une restriction sur l'opération: il s'attend à ce que l'opération retourne un élément, et accepte probablement aussi un élément comme argument. L'opération map itère sur une collection d'éléments, applique l'opération sur chaque élément et stocke finalement le résultat de chaque appel de l'opération dans une autre collection. En d'autres termes, le map transforme {[46] } une collection en une autre.

  2. foreach fonctionne avec une seule collection d'éléments. C'est la collection d'entrées.

    map fonctionne avec deux collections d'éléments: la collection d'entrée et la collection de sortie.

Ce n'est pas une erreur de relier les deux algorithmes: en fait, vous pouvez voir les deux hiérarchiquement, où map est une spécialisation de foreach. C'est-à-dire que vous pouvez utiliser foreach et que l'opération transforme son argument et insérez-le dans une autre collection. Ainsi, l'algorithme foreach est une abstraction, une généralisation, de l'algorithme map. En fait, parce que foreach n'a aucune restriction sur son fonctionnement, nous pouvons dire en toute sécurité que foreach est le mécanisme de boucle le plus simple, et il peut faire tout ce qu'une boucle peut faire. map, ainsi que d'autres algorithmes plus spécialisés, existe-t-il pour l'expressivité: si vous souhaitez mapper (ou transformer) une collection en une autre, votre intention est plus claire si vous utilisez map que si vous utilisez foreach.

Nous pouvons étendre cette discussion plus loin, et considérer l'algorithme copy: une boucle qui clone une collection. Cet algorithme est aussi une spécialisation de l'algorithme foreach. Vous pouvez définir une opération qui, étant donné un élément, insérera ce même élément dans une autre collection. Si vous utilisez foreach avec cette opération, vous avez effectivement effectué l'algorithme copy, mais avec une clarté, une expressivité ou une explicitation réduites. Prenons encore plus loin: nous pouvons dire que map est une spécialisation de copy, elle-même une spécialisation de foreach. map peutchanger l'un des éléments sur lesquels il itère. Si map ne change aucun des éléments, alors il suffit de copier les éléments, et en utilisant copy {[46] } exprimerait l'intention plus clairement.

L'algorithme foreach lui-même peut ou non avoir une valeur de retour, selon la langue. En C++, par exemple, foreach renvoie l'opération qu'il a reçue à l'origine. L'idée est que l' l'opération peut avoir un état, et vous voudrez peut-être que cette opération inspecte comment elle a évolué sur les éléments. map, aussi, peut ou ne peut pas renvoyer une valeur. En C++ transform (l'équivalent de map ici) arrive à renvoyer un itérateur à la fin du conteneur de sortie (collection). Dans Ruby, la valeur de retour de map est la séquence de sortie (collection). Ainsi, la valeur de retour des algorithmes est vraiment un détail d'implémentation; leur effet peut ou non être ce qu'ils retournent.

40
répondu wilhelmtell 2010-05-28 23:53:40

Array.protototype.map method & Array.protototype.forEach sont tous deux assez similaires.

Exécutez le code suivant: http://labs.codecademy.com/bw1/6#:workspace

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

arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

console.log();

arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

Ils donnent exactement le même résultat.

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

Mais la torsion vient quand vous exécutez le code suivant: -

ici, j'ai simplement assigné le résultat de la valeur de retour à partir des méthodes map et forEach.

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

var ar1 = arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar1);
console.log();

var ar2 = arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar2);
console.log();

Maintenant, le résultat est quelque chose délicat!

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

[ 1, 2, 3, 4, 5 ]

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

undefined

Conclusion

Array.prototype.map renvoie un tableau mais Array.prototype.forEach ne le fait pas.vous pouvez donc manipuler le tableau retourné à l'intérieur de la fonction de rappel transmise à la méthode map, puis le renvoyer.

Array.prototype.forEach marche seulement à travers le tableau donné afin que vous puissiez faire vos affaires tout en marchant dans le tableau.

30
répondu abhisekp 2016-02-02 11:19:15

La différence la plus "visible" est que map accumule le résultat dans une nouvelle collection, alors que foreach est fait uniquement pour l'exécution elle-même.

Mais il y a quelques hypothèses supplémentaires: puisque le' but ' de map est la nouvelle liste de valeurs, l'ordre d'exécution n'a pas vraiment d'importance. en fait, certains environnements d'exécution génèrent du code parallèle, ou même introduisent une mémorisation pour éviter d'appeler des valeurs répétées, ou la lazyness, pour éviter d'appeler certains à tout.

Foreach, d'autre part, est appelée spécifiquement pour les effets secondaires; par conséquent, l'ordre est important, et ne peuvent généralement pas être parallélisé.

11
répondu Javier 2014-01-25 15:52:46

Réponse Courte: map et forEach sont différents. En outre, de manière informelle, map est un surensemble strict de forEach.

Réponse longue: Tout d'abord, trouvons une description en une ligne de forEach et map:

  • forEach itère sur tous les éléments, en appelant la fonction fournie sur chacun.
  • map itère sur tous les éléments, appelant la fonction fournie sur chacun, et produit un tableau transformé en se souvenant du résultat de chaque fonction appeler.

Dans de nombreuses langues, forEach est souvent appelé each. La discussion suivante utilise JavaScript uniquement à titre de référence. Cela pourrait vraiment être n'importe quelle autre langue.

Maintenant, utilisons chacune de ces fonctions.

En utilisant forEach:

Tâche 1: écrivez une fonction printSquares, qui accepte un tableau de nombres arr, et imprime le carré de chaque élément.

Solution 1:

var printSquares = function (arr) {
    arr.forEach(function (n) {
        console.log(n * n);
    });
};

En utilisant map:

Tâche 2: Écrire une fonction selfDot, qui accepte un tableau de nombres arr, et retourne un tableau dans lequel chaque élément est le carré de l'élément correspondant dans arr.

Mis à part: ici, en termes d'argot, nous essayons de quadriller le tableau d'entrée. Formellement mis, Nous essayons de calculer son produit dot avec lui-même.

Solution 2:

var selfDot = function (arr) {
    return arr.map(function (n) {
        return n * n;
    });
};

Comment est map un surensemble de forEach?

Vous pouvez utiliser map, afin de résoudre des tâches, Tâche 1 et Tâche 2 . Cependant, vous ne pouvez pas utiliser forEach pour résoudre le 2.

Dans Solution 1, si vous remplacez simplement forEach par map, la solution sera toujours valide. Dans Solution 2 cependant, le remplacement de map par {[6] } va casser votre solution de travail précédente.

Implémentant forEach en termes de map:

Une autre façon de réaliser la supériorité de map est de mettre en œuvre forEach en termes de map. Comme nous sommes de bons programmeurs, nous ne nous laisserons pas aller dans l'espace de noms de la pollution. Nous appellerons notre forEach, juste each.

Array.prototype.each = function (func) {
    this.map(func);
};

Maintenant, si vous n'aimez pas le non-sens prototype, voilà:

var each = function (arr, func) {
    arr.map(func); // Or map(arr, func);
};

Alors, hum.. Pourquoi est-ce que forEach existe même?

, La réponse est l'efficacité. Si vous n'êtes pas intéressé par la transformation d'un tableau en un autre tableau, Pourquoi devriez-vous calculer le tableau transformé? Seulement pour le dump? Bien sûr que non! Si vous ne voulez pas d'une transformation, vous ne devriez pas faire une transformation.

Alors que la carte peut être utilisée pour résoudre Tâche 1 , Il ne devrait probablement pas. pour chacun est le bon candidat pour cela.


Réponse originale:

Bien que je sois largement d'accord avec la réponse de @madlep, je voudrais souligner que map() est un super-ensemble strict de forEach().

Oui map() est généralement utilisé pour créer un nouveau tableau. Cependant, il peut également être utilisé pour changer le tableau actuel.

Voici un exemple:

var a = [0, 1, 2, 3, 4], b = null;
b = a.map(function (x) { a[x] = 'What!!'; return x*x; });
console.log(b); // logs [0, 1, 4, 9, 16] 
console.log(a); // logs ["What!!", "What!!", "What!!", "What!!", "What!!"]

Dans l'exemple ci-dessus, a est idéalement définir de telle sorte que a[i] === i pour i < a.length. Même ainsi, il démontre la puissance de map().

Voici la description officielle de map(). Notez que map() peut même changer le tableau sur lequel il est appelé! Grêle map().

J'espère que cela a aidé.


Édité 10-Nov-2015: élaboration ajoutée.

11
répondu Sumukh Barve 2015-11-10 15:27:03

Voici un exemple dans Scala utilisant des listes: map renvoie la liste, foreach ne renvoie rien.

def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit

Donc map renvoie la liste résultant de l'application de la fonction f à chaque élément de liste:

scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

scala> list map (x => x * 2)
res0: List[Int] = List(2, 4, 6)

Foreach applique simplement f à chaque élément:

scala> var sum = 0
sum: Int = 0

scala> list foreach (sum += _)

scala> sum
res2: Int = 6 // res1 is empty
3
répondu irudyak 2014-05-13 07:56:27

Si vous parlez de Javascript en particulier, la différence est que map est une fonction de boucle tandis que forEach est un itérateur.

Utilisez map lorsque vous souhaitez appliquer une opération à chaque membre de la liste et récupérer les résultats en tant que nouvelle liste, sans affecter la liste d'origine.

Utiliser forEach lorsque vous souhaitez do quelque chose sur la base de chaque élément de la liste. Vous pourriez ajouter des choses à la page, par exemple. Essentiellement, il est idéal pour quand vous voulez "effets secondaires".

Autres différences: forEach ne renvoie rien (puisque c'est vraiment une fonction de flux de contrôle), et la fonction transmise obtient des références à l'index et à la liste entière, alors que map renvoie la nouvelle liste et ne passe que dans l'élément courant.

2
répondu phyzome 2008-12-10 02:19:28