244 votes

Y a-t-il une différence entre foreach et map ?

D'accord, il s'agit davantage d'une question d'informatique que d'une question basée sur un langage particulier, mais y a-t-il une différence entre une opération de map et une opération de foreach ? Ou sont-elles simplement des noms différents pour la même chose ?

0 votes

Curieusement, si j'obtiens un Iterator[String] depuis scala.io.Source.fromFile("/home/me/file").getLines() et j'applique .foreach(s => ptintln(s)) dessus, il est bien imprimé mais devient vide juste après. En même temps, si j'applique .map(ptintln(_)) dessus, il devient simplement vide et rien n'est imprimé.

327voto

madlep Points 14374

Différent.

foreach itère sur une liste et effectue une opération avec des effets secondaires sur chaque élément de la liste (comme par exemple sauvegarder chacun dans la base de données)

map itère sur une liste, crée un élément transformé pour chaque élément de cette liste, et retourne une autre liste de la même taille avec les éléments transformés (par exemple, convertir une liste de chaînes en majuscules)

0 votes

Merci, je pensais que c'était quelque chose dans ce sens mais je n'étais pas sûr!

21 votes

Mais vous pourriez également avoir des effets secondaires se produire dans la fonction de map aussi. J'aime cette réponse: stackoverflow.com/a/4927981/375688

7 votes

Un point important à mentionner ( ceci est particulièrement vrai en Scala ) est qu'un appel à map ne pas entraîne pas l'exécution de sa logique sous-jacente tant que la liste transformée attendue n'est pas requise. En revanche, l'opération de foreach est calculée immédiatement.

140voto

Henk Points 1903

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

0 votes

Merci! Maintenant je comprends la différence. Cela avait été confus pour moi pendant un certain temps

40voto

wilhelmtell Points 25504

En bref, foreach est utilisé pour appliquer une opération à chaque élément d'une collection d'éléments, tandis que map sert à transformer une collection en une autre.

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

  1. foreach n'a aucune restriction conceptuelle sur l'opération qu'il applique, à part peut-être accepter un élément en tant qu'argument. Autrement dit, l'opération peut ne rien faire, peut avoir un effet secondaire, peut retourner une valeur ou peut ne pas retourner de valeur. Tout ce qui importe à foreach est d'itérer sur une collection d'éléments et d'appliquer l'opération à chaque élément.

    map, en revanche, a une restriction sur l'opération : il attend que l'opération retourne un élément et probablement accepte également un élément en tant qu'argument. L'opération map itère sur une collection d'éléments, appliquant l'opération à chaque élément, et stocke finalement le résultat de chaque invocation de l'opération dans une autre collection. En d'autres termes, map transforme une collection en une autre.

  2. foreach fonctionne avec une seule collection d'éléments, qui est la collection d'entrée.

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

Il n'est pas faux de lier les deux algorithmes : en fait, vous pouvez considérer les deux hiérarchiquement, où map est une spécialisation de foreach. Autrement dit, vous pourriez utiliser foreach et faire en sorte que l'opération transforme son argument et l'insère dans une autre collection. Ainsi, l'algorithme foreach est une abstraction, une généralisation, de l'algorithme map. En fait, du fait que foreach n'a pas de restriction sur son opération, on peut dire en toute sécurité que foreach est le mécanisme de bouclage le plus simple qui soit, et il peut faire tout ce qu'une boucle peut faire. map, ainsi que d'autres algorithmes plus spécialisés, vise 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 pousser cette discussion plus loin en considérant également l'algorithme copy : une boucle qui clone une collection. Cet algorithme est également une spécialisation de l'algorithme foreach. Vous pourriez 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 en fait effectué l'algorithme copy, bien que cela soit moins clair, expressif ou explicite. Allons encore plus loin : nous pouvons dire que map est une spécialisation de copy, lui-même une spécialisation de foreach. map peut modifier certains des éléments qu'il itère. Si map ne modifie aucun des éléments, il s'est simplement contenté de copier les éléments, et utiliser copy exprimerait plus clairement l'intention.

L'algorithme foreach pourrait lui-même avoir ou non une valeur de retour, en fonction du langage. En C++, par exemple, foreach renvoie l'opération qu'il a reçue d'origine. L'idée est que l'opération pourrait avoir un état, et vous voudriez récupérer cette opération pour inspecter comment elle a évolué sur les éléments. map, lui aussi, pourrait ou non renvoyer une valeur. En C++, transform (l'équivalent de map ici) renvoie un itérateur à la fin du conteneur de sortie (collection). En 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 être ou non ce qu'ils renvoient.

0 votes

Pour un exemple de comment .forEach() peut être utilisé pour implémenter .map(), voir ici : stackoverflow.com/a/39159854/1524693

34voto

abhisekp Points 73

La méthode Array.prototype.map et la méthode Array.prototype.forEach sont toutes 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 différence vient lorsque vous exécutez le code suivant :

Ici, j'ai simplement attribué le résultat de la valeur de retour 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 de 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

La méthode Array.prototype.map renvoie un tableau mais la méthode Array.prototype.forEach ne le fait pas. Vous pouvez donc manipuler le tableau renvoyé à l'intérieur de la fonction de rappel passée à la méthode map, puis le renvoyer.

La méthode Array.prototype.forEach parcourt simplement le tableau donné afin que vous puissiez faire vos manipulations tout en parcourant le tableau.

11voto

Javier Points 33134

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

Mais il y a quelques suppositions supplémentaires : comme 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 introduisent même une sorte de mémoïsation pour éviter d'appeler des valeurs répétées, ou de la paresse pour éviter d'appeler certaines valeurs du tout.

En revanche, foreach est appelé spécifiquement pour les effets de bord; par conséquent, l'ordre est important, et généralement ne peut pas être parallélisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X