简体   繁体   English

forEach 和 map 之间的最大区别是什么?

[英]What is the big difference between forEach and map?

Here's something I don't understand.这是我不明白的事情。 The map function, which I just learned about a few days ago, is supposed to be some amazing function that will transform the way I write code if I find uses for it.我几天前刚了解到的map function 应该是一些了不起的东西 function 如果我找到它的用途,它将改变我编写代码的方式。 But I still don't see how it's any different than forEach .但我仍然看不出它与forEach有什么不同。 The only difference is that the function passed to map replaces the current element with the return value.唯一的区别是传递给map的 function 用return值替换了当前元素。 But forEach can do that too, which means that map is just a less general version of forEach .但是forEach也可以做到这一点,这意味着map只是forEach的一个不太通用的版本。

Example on MDN: MDN 上的示例:

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots is now [1, 2, 3], numbers is still [1, 4, 9]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Ok, cool, I guess?好的,很酷,我猜?

I can do that with forEach :我可以用forEach做到这一点:

var numbers = [1, 4, 9];
var roots = numbers.forEach(function(el){el=Math.sqrt(el);});
// roots is now [1, 2, 3], numbers is still [1, 4, 9]

Other example:其他例子:

var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray is now [{1:10}, {2:20}, {3:30}], 
// kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]

I can do that with forEach and it looks almost identical.我可以用forEach做到这一点,它看起来几乎相同。

What's so good about map ? map什么好处? What is an example where it works super-well where forEach wouldn't work?什么是它在forEach不起作用的地方工作得很好的例子?

The difference is that forEach "iterates over an array" and map "iterates over an array and returns the result "不同之处在于forEach “遍历数组”和map “遍历数组并返回结果

var numbers = [1, 4, 9];

var roots = numbers.forEach(Math.sqrt);
// roots is undefined, numbers is still [1, 4, 9]

var roots = numbers.map(Math.sqrt);
// roots is [1, 2, 3], numbers is still [1, 4, 9]

What's so good about map ? map什么好? It keeps your code small and smart because you don't need to define anonymous functions for built-in functions.它使您的代码小巧而智能,因为您不需要为内置函数定义匿名函数。

var numbers = [1, 4, 9];

var roots = [];
numbers.forEach(function(val){ roots.push( Math.sqrt(val) ); });
// roots is now [1, 2, 3], numbers is still [1, 4, 9]

The value of returning the result (no pun intended) is proven in your existing example...返回结果(没有双关语)的价值在您现有的示例中得到了证明......

var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ // <---------------- map
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray is now [{1:10}, {2:20}, {3:30}], 
// kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]

var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.forEach(function(obj){ // <---------------- forEach
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray is now undefined, 
// kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]

map地图

map iterates over a list and returns a new list, without changing anything else. map遍历一个列表并返回一个新列表,不更改任何其他内容。 It doesn't change the original list.它不会更改原始列表。 It has no side effects.它没有副作用。 With map you can take a normal function that works with primitives and lift this function, so that it can work with lists of these primitives:使用map您可以使用一个与原语一起工作的普通函数并提升这个函数,以便它可以与这些原语的列表一起工作:

const map = (f, xs) => xs.map(x => f(x));
const sqr = x => x * x;

let xs = [1,2,3];
let x = 3;

sqr(x); // 9
sqr(xs); // Error
let ys = map(sqr, xs); // [1,4,9]
xs; // [1,2,3]

The example illustrates how map lifts sqr in the context of xs , so that it can square the elements of xs .该示例说明了map如何在xs的上下文中提升sqr ,以便它可以对xs的元素进行平方。 In this way you can reuse normal functions for arrays.通过这种方式,您可以为数组重用普通函数。

forEach为每个

forEach has no result value. forEach没有结果值。 A function without any result value is useless, unless it has some side effects.一个没有任何结果值的函数是没有用的,除非它有一些副作用。 Hence forEach have to apply side effects to the elements it is iterating over, in order to do something meaningful:因此forEach必须对其迭代的元素应用副作用,以便做一些有意义的事情:

let ys = xs.forEach(sqr); // undefined
xs; // [1,2,3]
// without side effects, nothing has happened

const sqrWithSideEffect = (x, idx, arr) => arr[idx] = x * x; // ugly, isn't it?
xs.forEach(sqrWithSideEffect); // 
xs; // [1,4,9]; // side effect: destructive update of xs

Conclusion : forEach comes from imperative, map from functional programming.结论forEach来自命令式, map来自函数式编程。 Both represent opposing paradigms.两者都代表了对立的范式。 So if you really want to understand the consequences of the differences between the two functions, you have to understand the differences between the two programming paradigms.所以如果你真的想了解这两个函数之间差异的后果,你必须了解这两种编程范式之间的差异。

forEach vs. Map High Order Array Methods forEach 与 Map 高阶数组方法

const arr = [1,2,3]
const arr2 = [...arr,4,5]//see spread operator grepper answer for [...arr]
//the forEach doesn't return anything, it just loops through the array
arr2.forEach(function(item) {
  console.log(item + ' of ' + arr2.length)
})
//map allows us to return an array and store it into a new array
const arr3 = arr2.map(function(item) {
  //after performing some operation on all the objects of the array
  //we can then return all those values into a new array
  return item * 2
})

console.log(arr3)

Chack it查查它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM