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?
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?
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)
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'ils foreach
ne renvoient rien. map
est généralement utilisé lorsque vous souhaitez transformer une collection d'éléments avec une fonction, alors qu'il foreach
exécute simplement une action pour chaque élément.
En bref, foreach
c'est pour appliquer une opération sur chaque élément d'une collection d'éléments, alors map
c'est pour transformer une collection en une autre.
Il existe deux différences importantes entre foreach
et map
.
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 compte foreach
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, le map
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 de foreach
. Autrement dit, vous pouvez utiliser foreach
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'il foreach
n'y a aucune restriction sur son fonctionnement, nous pouvons dire en toute sécurité que foreach
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 utilisez map
que si vous utilisez foreach
.
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 utilisez foreach
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 que map
c'est une spécialisation de copy
, elle-même une spécialisation de foreach
. map
peut modifier l' un des éléments sur lesquels il itère. Si map
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'équivalent 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 être ou non ce qu'ils retournent.
.forEach()
peut être utilisé pour l'implémentation .map()
, voir ici: stackoverflow.com/a/39159854/1524693
Array.protototype.map
méthode et 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 le résultat idem exact.
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
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
Array.prototype.map
renvoie un tableau mais Array.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 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.
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 des descriptions d'une ligne de forEach
et map
:
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é juste each
. 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.
forEach
:Tâche 1: écrivez une fonction printSquares
qui accepte un tableau de nombres arr
et imprime le carré de chaque élément qu'il contient.
Solution 1:
var printSquares = function (arr) {
arr.forEach(function (n) {
console.log(n * n);
});
};
map
:Tâche 2: écrire une fonction selfDot
qui accepte un tableau de nombres arr
et renvoie un tableau dans lequel chaque élément est le carré de l'élément correspondant dans arr
.
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:
var selfDot = function (arr) {
return arr.map(function (n) {
return n * n;
});
};
map
un surensemble de forEach
?Vous pouvez utiliser map
pour résoudre les deux tâches, Tâche 1 et Tâche 2 . Cependant, vous ne pouvez pas utiliser forEach
pour résoudre la tâche 2 .
Dans la solution 1 , si vous remplacez simplement forEach
par map
, la solution sera toujours valide. Cependant, dans la solution 2 , le remplacement map
par forEach
interrompra votre solution qui fonctionnait auparavant.
forEach
en œuvre en termes de map
:Une autre façon de réaliser map
la supériorité de est de mettre forEach
en œuvre en termes de map
. Comme nous sommes de bons programmeurs, nous ne nous livrerons pas à la pollution de l'espace de noms. Nous appellerons notre forEach
, juste each
.
Array.prototype.each = function (func) {
this.map(func);
};
Maintenant, si vous n'aimez pas le prototype
non - sens, c'est parti:
var each = function (arr, func) {
arr.map(func); // Or map(arr, func);
};
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.
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 de forEach()
.
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:
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 a
été commodément réglé de telle sorte que a[i] === i
pour i < a.length
. Même ainsi, cela démontre la puissance de map()
.
Voici la description officielle demap()
. Notez que cela map()
peut même changer le tableau sur lequel il est appelé! Salut map()
.
J'espère que cela vous a aidé.
Édité le 10 novembre 2015: ajout de l'élaboration.
map
fonction mais non forEach
; ne pourriez-vous pas simplement ne pas utiliser à la map
place de forEach
? D'un autre côté, si une langue avait forEach
mais non map
, vous devez implémenter la vôtre map
. Vous ne pouvez pas simplement utiliser à la forEach
place de map
. Dis-moi ce que tu penses.
Voici un exemple dans Scala utilisant des listes: la carte renvoie la liste, foreach ne renvoie rien.
def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit
Ainsi, map renvoie la liste résultant de l'application de la fonction f à chaque élément de la 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
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.
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 dit
Fichier "<stdin>", ligne 5, dans <module>
AttributeError: l'objet 'NoneType' n'a pas d'attribut 'collect'
nums = sc.parallelize([1,2,3,4,5,6,7,8,9,10])
num2 = nums.map(lambda x: x+2)
print ("num2",num2.collect())
num3 = nums.foreach(lambda x : x*x)
print ("num3",num3.collect())
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é.