map和reduce的主要区别


83

我使用了这两种方法,但是对于这两种方法的使用我很困惑。

有什么map可以做但不能做的reduce,反之亦然?

注意:我知道如何使用这两种方法,我在质疑这些方法与何时需要使用它们之间的主要区别。

Answers:


228

资源

双方mapreduce具有作为输入数组,你定义一个函数。它们在某种程度上是互补的:map不能为多个元素的数组返回单个元素,而reduce总是返回最终更改的累加器。

map

使用map您迭代元素,并为每个元素返回所需的元素。

例如,如果您有一个数字数组并想要得到它们的平方,则可以执行以下操作:

// A function which calculates the square
const square = x => x * x

// Use `map` to get the square of each number
console.log([1, 2, 3, 4, 5].map(square))

reduce

使用数组作为输入,您可以基于获取accumulatorcurrent_element参数的回调函数(第一个参数)来获得一个单个元素(例如,对象,数字或另一个数组):

const numbers = [1, 2, 3, 4, 5]

// Calculate the sum
console.log(numbers.reduce(function (acc, current) {
  return acc + current
}, 0)) // < Start with 0

// Calculate the product
console.log(numbers.reduce(function (acc, current) {
  return acc * current
}, 1)) // < Start with 1


两者都可以做相同的事情时,您应该选择哪一个?尝试想象一下代码的外观。对于所提供的示例,您可以使用来像您提到的那样计算squares数组reduce

// Using reduce
[1, 2, 3, 4, 5].reduce(function (acc, current) {
    acc.push(current*current);
    return acc;
 }, [])

 // Using map
 [1, 2, 3, 4, 5].map(x => x * x)

现在,看看这些,显然第二种实现看起来更好,而且更短。通常,您会选择更清洁的解决方案,在这种情况下为map。当然,您可以使用进行操作reduce,但总而言之,请考虑将其缩短并最终将变得更好。


2
好的,我看到您的Map示例,但是我可以使用reduce函数做同样的事情,为什么呢?使用map减少或修改现有数组来创建新数组。
Nishant Dixit

@NishantDixit您能用什么做同样的事情reduce?您不能,那是我在这些示例中试图展示的。
尼卡比曹

我在下面的注释中添加reduce方法,该方法计算给定的平方并返回新数组。
Nishant Dixit

console.log([1, 2, 3, 4, 5].reduce(function (acc, current) { acc.push( current = current*current); return acc; }, []))
Nishant Dixit

2
在选择使用哪个时,意图是关键。如果两者都能取得相似的结果,并且由于性能差异可以忽略不计,请使用与您的意图相匹配的函数,例如Tadman在下面的“当您映射时”,您正在编写一个函数,该函数将f(x)的x转换为一些新的值x1。“减少”时,您正在编写一些函数g(y),它接受数组y并发出数组y1”。
f0rfun

17

通常,“映射”是指将一系列输入转换为等长的一系列输出,而“减少”是指将一系列输入转换为少量的输出。

人们所说的“ map-reduce”通常被理解为“变换,可能并行,串行组合”。

当“地图”,你写一个函数变换xf(x)进入一些新的价值x1。当您“减少”时,您正在编写一些g(y)接受arrayy并发出array的函数y1。他们处理不同类型的数据并产生不同的结果。


实际上,两者都是数据类型无关的,不是“它们可以处理不同类型的数据...”对吗?
约翰·彼得斯


6

map()函数通过在输入数组中的每个元素上传递函数来返回新数组。

这与以reduce()相同的方式获取数组和函数不同,但是该函数接受2输入-累加器和当前值。

因此,reduce()可以像map()总是.concat将某个函数的下一个输出放到累加器上一样使用。但是,更常用的方法是减小数组的尺寸,以便采用一维并返回单个值或展平二维数组等。


5

让我们一一看一下这两个。

地图

Map会执行回调,并针对数组中的每个元素运行它,但它的独特之处在于它会基于现有数组生成一个新数组

var arr = [1, 2, 3];

var mapped = arr.map(function(elem) {
    return elem * 10;
})

console.log(mapped); // it genrate new array

降低

数组对象的reduce方法用于将数组缩小为一个单一值

var arr = [1, 2, 3];

var sum = arr.reduce(function(sum, elem){
    return sum + elem;
})

console.log(sum) // reduce the array to one single value


3

要了解map,filter和reduce的区别,请记住以下几点:

  1. 这三种方法都适用于数组,因此,只要您想对数组进行任何操作,都将使用这些方法。
  2. 这三种方法都遵循功能性方法,因此原始数组保持不变。原始数组不变,而是返回一个新的数组/值。
  3. Map 返回一个新的等于no的数组。原始数组中存在的元素数。因此,如果原始数组有5个元素,则返回的数组也将有5个元素。每当我们要对数组的每个元素进行一些更改时,都会使用此方法。您可能还记得,an数组的每个元素都被映射到输出数组中的某个新值,因此名称map 为例如

var originalArr = [1,2,3,4]
//[1,2,3,4]
var squaredArr = originalArr.map(function(elem){
  return Math.pow(elem,2);
});
//[1,4,9,16]

  1. Filter 返回一个新数组,该数组的元素数等于或少于原始数组。它返回数组中已通过某些条件的那些元素。当我们要在原始数组上应用过滤器时使用此方法,因此名称为filter。例如

var originalArr = [1,2,3,4]
//[1,2,3,4]
var evenArr = originalArr.filter(function(elem){
  return elem%2==0;
})
//[2,4]

  1. Reduce返回一个值,与映射/过滤器不同。因此,每当我们要在数组的所有元素上运行操作但要使用所有元素进行单个输出时,都使用reduce。您可以记住,数组的输出减少为一个值,因此名称为reduce。例如

var originalArr = [1,2,3,4]
//[1,2,3,4]
var sum = originalArr.reduce(function(total,elem){
  return total+elem;
},0)
//10

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.