好吧,这更像是一个计算机科学问题,而不是一个基于特定语言的问题,但是map操作和foreach操作之间有区别吗?或者它们只是同一事物的不同名称?


当前回答

如果你特别谈论Javascript,区别在于map是一个循环函数,而forEach是一个迭代器。

当您希望对列表的每个成员应用操作并将结果作为新列表返回时,使用map,而不影响原始列表。

当您想在列表的每个元素的基础上做一些事情时,请使用forEach。例如,您可能正在向页面添加内容。从本质上讲,当你想要“副作用”时,它是很好的。

其他区别:forEach不返回任何内容(因为它实际上是一个控制流函数),传入函数获得对索引和整个列表的引用,而map返回新的列表,只传入当前元素。

其他回答

下面是一个Scala中使用列表的例子:map返回列表,foreach不返回任何内容。

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

map返回函数f作用于每个列表元素后得到的列表:

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只是对每个元素应用f:

scala> var sum = 0
sum: Int = 0

scala> list foreach (sum += _)

scala> sum
res2: Int = 6 // res1 is empty

ForEach尝试在RDD的每个元素上应用一个函数,比如写入db等,而不返回任何东西。

但是map()在rdd的元素上应用一些函数并返回rdd。所以当你运行下面的方法时,它不会在第3行失败,但在应用foreach后收集rdd时,它会失败并抛出一个错误

文件"<stdin>",第5行,在<模块> AttributeError: 'NoneType'对象没有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())

不同。

Foreach遍历一个列表,并对每个列表成员执行一些具有副作用的操作(例如将每个成员保存到数据库中)

Map遍历一个列表,转换该列表的每个成员,并返回另一个具有已转换成员的相同大小的列表(例如将字符串列表转换为大写)

它们之间的重要区别是map将所有结果累积到一个集合中,而foreach不返回任何结果。Map通常用于使用函数转换元素集合,而foreach只是为每个元素执行一个操作。

简而言之,foreach用于对元素集合中的每个元素应用操作,而map用于将一个集合转换为另一个集合。

foreach和map之间有两个显著的区别。

foreach has no conceptual restrictions on the operation it applies, other than perhaps accept an element as argument. That is, the operation may do nothing, may have a side-effect, may return a value or may not return a value. All foreach cares about is to iterate over a collection of elements, and apply the operation on each element. map, on the other hand, does have a restriction on the operation: it expects the operation to return an element, and probably also accept an element as argument. The map operation iterates over a collection of elements, applying the operation on each element, and finally storing the result of each invocation of the operation into another collection. In other words, the map transforms one collection into another. foreach works with a single collection of elements. This is the input collection. map works with two collections of elements: the input collection and the output collection.

It is not a mistake to relate the two algorithms: in fact, you may view the two hierarchically, where map is a specialization of foreach. That is, you could use foreach and have the operation transform its argument and insert it into another collection. So, the foreach algorithm is an abstraction, a generalization, of the map algorithm. In fact, because foreach has no restriction on its operation we can safely say that foreach is the simplest looping mechanism out there, and it can do anything a loop can do. map, as well as other more specialized algorithms, is there for expressiveness: if you wish to map (or transform) one collection into another, your intention is clearer if you use map than if you use foreach.

We can extend this discussion further, and consider the copy algorithm: a loop which clones a collection. This algorithm too is a specialization of the foreach algorithm. You could define an operation that, given an element, will insert that same element into another collection. If you use foreach with that operation you in effect performed the copy algorithm, albeit with reduced clarity, expressiveness or explicitness. Let's take it even further: We can say that map is a specialization of copy, itself a specialization of foreach. map may change any of the elements it iterates over. If map doesn't change any of the elements then it merely copied the elements, and using copy would express the intent more clearly.

The foreach algorithm itself may or may not have a return value, depending on the language. In C++, for example, foreach returns the operation it originally received. The idea is that the operation might have a state, and you may want that operation back to inspect how it evolved over the elements. map, too, may or may not return a value. In C++ transform (the equivalent for map here) happens to return an iterator to the end of the output container (collection). In Ruby, the return value of map is the output sequence (collection). So, the return value of the algorithms is really an implementation detail; their effect may or may not be what they return.