Ok, c'est plus une question d'informatique qu'une question basée sur une langue particulière, mais y a-t-il une différence entre une opération de carte et une opération foreach? Ou s'agit-il simplement de noms différents pour la même chose?
foreach
language-agnostic
computer-science
map-function
Robert Gould
la source
la source
Iterator[String]
descala.io.Source.fromFile("/home/me/file").getLines()
et que je l' applique.foreach(s => ptintln(s))
, il est imprimé correctement mais se vide juste après. En même temps, si je l'applique.map(ptintln(_))
, il devient vide et rien n'est imprimé.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)
la source
map
ne pas entraîner l'exécution de sa logique sous - jacente jusqu'au moment où la liste transformée attendu est convoqué. En revanche,foreach
le fonctionnement de est calculé immédiatement.La différence importante entre eux est qu'ils
map
accumulent tous les résultats dans une collection, alors qu'ilsforeach
ne renvoient rien.map
est généralement utilisé lorsque vous souhaitez transformer une collection d'éléments avec une fonction, alors qu'ilforeach
exécute simplement une action pour chaque élément.la source
En bref,
foreach
c'est pour appliquer une opération sur chaque élément d'une collection d'éléments, alorsmap
c'est pour transformer une collection en une autre.Il existe deux différences importantes entre
foreach
etmap
.foreach
n'a aucune restriction conceptuelle sur l'opération qu'il applique, à part peut-être accepter un élément comme argument. Autrement dit, l'opération peut ne rien faire, peut avoir un effet secondaire, peut renvoyer une valeur ou peut ne pas retourner une valeur. Tout ce qui compteforeach
est d'itérer sur une collection d'éléments et d'appliquer l'opération sur chaque élément.map
, d'autre part, 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'map
opération parcourt une collection d'éléments, en appliquant l'opération sur chaque élément, et enfin en stockant le résultat de chaque appel de l'opération dans une autre collection. En d'autres termes, lemap
transforme une collection en une autre.foreach
fonctionne avec une seule collection d'éléments. Il s'agit de 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ù se
map
trouve une spécialisation deforeach
. Autrement dit, vous pouvez utiliserforeach
et faire transformer l'opération par son argument et l'insérer dans une autre collection. Ainsi, l'foreach
algorithme est une abstraction, une généralisation de l'map
algorithme. En fait, parce qu'ilforeach
n'y a aucune restriction sur son fonctionnement, nous pouvons dire en toute sécurité queforeach
c'est le mécanisme de boucle le plus simple qui existe et qu'il peut faire tout ce qu'une boucle peut faire.map
, ainsi que d'autres algorithmes plus spécialisés, sont là pour l'expressivité: si vous souhaitez mapper (ou transformer) une collection en une autre, votre intention est plus claire si vous utilisezmap
que si vous utilisezforeach
.Nous pouvons approfondir cette discussion et considérer l'
copy
algorithme: une boucle qui clone une collection. Cet algorithme est également une spécialisation de l'foreach
algorithme. 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 utilisezforeach
cette opération, vous avez en fait exécuté l'copy
algorithme, mais avec une clarté, une expressivité ou une explication réduites. Allons plus loin: nous pouvons dire quemap
c'est une spécialisation decopy
, elle-même une spécialisation deforeach
.map
peut modifier l' un des éléments sur lesquels il itère. Simap
ne modifie aucun des éléments, il a simplement copié les éléments et utilisé la copie exprimerait l'intention plus clairement.L'
foreach
algorithme 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 initialement reçue. L'idée est que l'opération peut avoir un état, et vous souhaiterez peut-être que cette opération revienne sur son évolution au fil des éléments.map
peut également renvoyer une valeur. En C ++transform
(l'équivalentmap
ici) arrive à renvoyer un itérateur à la fin du conteneur de sortie (collection). Dans Ruby, la valeur de retour demap
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 retournent.la source
.forEach()
peut être utilisé pour l'implémentation.map()
, voir ici: stackoverflow.com/a/39159854/1524693Array.protototype.map
méthode etArray.protototype.forEach
sont tous deux assez similaires.Exécutez le code suivant: http://labs.codecademy.com/bw1/6#:workspace
Ils donnent le résultat idem exact.
Mais la torsion survient 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.
Maintenant, le résultat est quelque chose de délicat!
Conclusion
Array.prototype.map
renvoie un tableau maisArray.prototype.forEach
pas. Vous pouvez donc manipuler le tableau retourné à l'intérieur de la fonction de rappel passée à la méthode map, puis le renvoyer.Array.prototype.forEach
marche uniquement à travers le tableau donné afin que vous puissiez faire votre travail tout en parcourant le tableau.la source
la différence la plus «visible» est que map accumule le résultat dans une nouvelle collection, tandis que foreach n'est fait que 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, peu importe l'ordre d'exécution. en fait, certains environnements d'exécution génèrent du code parallèle, ou même introduisent une certaine mémorisation pour éviter d'appeler des valeurs répétées, ou la paresse, pour éviter d'en appeler du tout.
foreach, d'autre part, est appelé spécifiquement pour les effets secondaires; par conséquent, l'ordre est important et ne peut généralement pas être mis en parallèle.
la source
Réponse courte:
map
etforEach
sont différents. En outre, de manière informelle,map
est un surensemble strict deforEach
.Réponse longue: Tout d'abord, trouvons des descriptions d'une ligne de
forEach
etmap
:forEach
itère sur tous les éléments, appelant la fonction fournie sur chacun.map
itère sur tous les éléments, appelle la fonction fournie sur chacun et produit un tableau transformé en se souvenant du résultat de chaque appel de fonction.Dans de nombreuses langues,
forEach
est souvent appelé justeeach
. La discussion suivante utilise JavaScript uniquement à titre de référence. Ce pourrait ê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 nombresarr
et imprime le carré de chaque élément qu'il contient.Solution 1:
En utilisant
map
:Tâche 2: écrire une fonction
selfDot
qui accepte un tableau de nombresarr
et renvoie un tableau dans lequel chaque élément est le carré de l'élément correspondant dansarr
.En plus: Ici, en termes d'argot, nous essayons de cadrer le tableau d'entrée. Formellement, nous essayons de calculer son produit scalaire avec lui-même.
Solution 2:
Comment est
map
un surensemble deforEach
?Vous pouvez utiliser
map
pour résoudre les deux tâches, Tâche 1 et Tâche 2 . Cependant, vous ne pouvez pas utiliserforEach
pour résoudre la tâche 2 .Dans la solution 1 , si vous remplacez simplement
forEach
parmap
, la solution sera toujours valide. Cependant, dans la solution 2 , le remplacementmap
parforEach
interrompra votre solution qui fonctionnait auparavant.Mise
forEach
en œuvre en termes demap
:Une autre façon de réaliser
map
la supériorité de est de mettreforEach
en œuvre en termes demap
. Comme nous sommes de bons programmeurs, nous ne nous livrerons pas à la pollution de l'espace de noms. Nous appellerons notreforEach
, justeeach
.Maintenant, si vous n'aimez pas le
prototype
non - sens, c'est parti:Alors, euh .. Pourquoi ça
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 vider? Bien sûr que non! Si vous ne voulez pas de transformation, vous ne devriez pas faire de transformation.
Ainsi, bien que la carte puisse être utilisée pour résoudre la tâche 1 , elle ne devrait probablement pas. Car 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 qu'il
map()
s'agit d'un super-ensemble strict deforEach()
.Oui,
map()
est généralement utilisé pour créer un nouveau tableau. Cependant, il peut également être utilisé pour modifier le tableau actuel.Voici un exemple:
Dans l'exemple ci-dessus, a
a
été commodément réglé de telle sorte quea[i] === i
pouri < a.length
. Même ainsi, cela démontre la puissance demap()
.Voici la description officielle de
map()
. Notez que celamap()
peut même changer le tableau sur lequel il est appelé! Salutmap()
.J'espère que cela vous a aidé.
Édité le 10 novembre 2015: ajout de l'élaboration.
la source
map
fonction mais nonforEach
; ne pourriez-vous pas simplement ne pas utiliser à lamap
place deforEach
? D'un autre côté, si une langue avaitforEach
mais nonmap
, vous devez implémenter la vôtremap
. Vous ne pouvez pas simplement utiliser à laforEach
place demap
. Dis-moi ce que tu penses.Voici un exemple dans Scala utilisant des listes: la carte renvoie la liste, foreach ne renvoie rien.
Ainsi, map renvoie la liste résultant de l'application de la fonction f à chaque élément de la liste:
Foreach applique simplement f à chaque élément:
la source
Si vous parlez de Javascript en particulier, la différence est qu'il
map
s'agit d'une fonction de boucle et d'forEach
un itérateur.À utiliser
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 voulez faire quelque chose sur la base de chaque élément de la liste. Vous pourriez ajouter des éléments à la page, par exemple. Essentiellement, c'est génial quand vous voulez des "effets secondaires".Autres différences:
forEach
ne renvoie rien (car il s'agit vraiment d'une fonction de flux de contrôle), et la fonction transmise obtient des références à l'index et à la liste entière, tandis que map renvoie la nouvelle liste et ne passe que dans l'élément actuel.la source
ForEach essaie d'appliquer une fonction telle que l'écriture dans db etc sur chaque élément du RDD sans rien renvoyer.
Mais le
map()
applique une fonction sur les éléments de rdd et renvoie le rdd. Ainsi, lorsque vous exécutez la méthode ci-dessous, elle n'échouera pas à la ligne 3, mais lors de la collecte du rdd après avoir appliqué foreach, elle échouera et générera une erreur qui ditla source