好吧,这更像是一个计算机科学问题,而不是一个基于特定语言的问题,但是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.
其他回答
array . prototype .map方法和array . prototype . foreach方法都非常相似。
运行如下代码: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));
});
它们给出了完全相同的结果。
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
但当你运行以下代码时,扭转就来了:-
这里我只是简单地分配了map和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();
现在的结果有些棘手!
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返回一个数组,但array .prototype. foreach不返回。因此,您可以在传递给map方法的回调函数中操作返回的数组,然后返回它。
foreach只遍历给定的数组,所以你可以在遍历数组时做你的事情。
如果你特别谈论Javascript,区别在于map是一个循环函数,而forEach是一个迭代器。
当您希望对列表的每个成员应用操作并将结果作为新列表返回时,使用map,而不影响原始列表。
当您想在列表的每个元素的基础上做一些事情时,请使用forEach。例如,您可能正在向页面添加内容。从本质上讲,当你想要“副作用”时,它是很好的。
其他区别:forEach不返回任何内容(因为它实际上是一个控制流函数),传入函数获得对索引和整个列表的引用,而map返回新的列表,只传入当前元素。
简单的回答:map和forEach是不同的。另外,非正式地说,map是forEach的严格超集。
长回答:首先,让我们提出forEach和map的一行描述:
forEach遍历所有元素,在每个元素上调用所提供的函数。 Map遍历所有元素,在每个元素上调用所提供的函数,并通过记住每个函数调用的结果来生成转换后的数组。
在许多语言中,forEach通常被称为each。下面的讨论使用JavaScript仅供参考。它真的可以是任何其他语言。
现在,让我们分别使用这些函数。
使用forEach:
任务1:编写printSquares函数,该函数接受数字数组arr,并打印其中每个元素的平方。
解决方案1:
var printSquares = function (arr) {
arr.forEach(function (n) {
console.log(n * n);
});
};
使用地图:
任务2:编写一个函数selfDot,它接受一个数字数组arr,并返回一个数组,其中每个元素都是arr中相应元素的平方。
旁白:在这里,在俚语中,我们试图平方输入数组。正式地说,我们试着计算它与自身的点积。
解决方案2:
var selfDot = function (arr) {
return arr.map(function (n) {
return n * n;
});
};
map如何是forEach的超集?
您可以使用map来解决任务1和任务2。但是,您不能使用forEach来解决任务2。
在解决方案1中,如果简单地用map替换forEach,解决方案仍然有效。然而,在解决方案2中,用forEach替换map将破坏之前的工作解决方案。
在map方面实现forEach:
实现map优势的另一种方法是根据map实现forEach。由于我们是优秀的程序员,我们不会沉迷于名称空间污染。我们将调用forEach。
Array.prototype.each = function (func) {
this.map(func);
};
现在,如果你不喜欢毫无意义的原型,你可以这样做:
var each = function (arr, func) {
arr.map(func); // Or map(arr, func);
};
所以,嗯. .forEach为什么会存在?
答案是效率。如果您对将一个数组转换为另一个数组不感兴趣,为什么要计算转换后的数组呢?只是为了把它扔掉?当然不是!如果你不想做变换,你就不应该做变换。
因此,虽然map可以用于解决任务1,但它可能不应该使用。因为每个人都是正确的候选人。
最初的回答:
虽然我在很大程度上同意@madlep的回答,但我想指出map()是forEach()的严格超集。
是的,map()通常用于创建一个新数组。但是,它也可以用来改变当前数组。
这里有一个例子:
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!!"]
在上面的例子中,a被方便地设置为a[i] === i对于i < a.length。尽管如此,它还是展示了map()的强大功能。
下面是map()的官方描述。注意map()甚至可能改变调用它的数组!冰雹(地图)。
希望这对你有所帮助。
编辑2015年11月10日:增加详细说明。
它们之间的重要区别是map将所有结果累积到一个集合中,而foreach不返回任何结果。Map通常用于使用函数转换元素集合,而foreach只是为每个元素执行一个操作。
下面是一个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和map有区别吗?
- 使用c++ 11的基于范围的正确方法是什么?
- 设计模式:工厂vs工厂方法vs抽象工厂
- 我如何应用for-each循环到字符串中的每个字符?
- 在PHP中使用foreach循环时查找数组的最后一个元素
- 为什么处理排序数组比未排序数组慢?
- 构造函数何时抛出异常是正确的?
- 什么是“一级”对象?
- 什么时候应该使用Debug.Assert()?
- 为什么浮点数不准确?
- 我在PHP中有2个日期,我如何运行foreach循环来遍历所有这些日子?
- IOException:进程不能访问文件“文件路径”,因为它正在被另一个进程使用
- 地图和字典的区别是什么?
- 跳跃表vs.二叉搜索树
- Kotlin中的' forEach '中的' break '和' continue '