发布于 2026-01-06 0 阅读
0

JavaScript 中的 Map、Filter 和 Reduce

JavaScript 中的 Map、Filter 和 Reduce

本文是对 JavaScript 的 map、filter 和 reduce 方法的基本介绍,并提供了 JavaScript 函数式编程的实际应用案例。

它们有什么共同点?

  • 这三个函数都是数组方法(即可以对数组变量调用的方法)。
  • 每个函数返回的值都是一个新数组,其中包含对您提供的函数中原始数组执行的操作的结果。

地图

  • map()方法允许您遍历数组中的每个元素,然后通过使用提供的函数以任何所需的方式操作每个元素。
  • 提供的函数可以是匿名函数,也可以是命名函数。
  • 需要特别注意的是,只有当您期望函数返回值时才应使用此方法。否则,如果您想修改原始数组,map()建议使用 JavaScript 的 ` get` 方法。forEach()
  • TL;DR -map()是一个for带有返回值的循环。

基本示例

  • 这是MDN网页上提供的关于该map()方法的一个简单示例。
const evenNumbers = [2, 4, 6]

const result = evenNumbers.map(currentValue => currentValue * 2)

// result = [4, 8, 12]

实际应用案例

  • 这是你经常会遇到的情况:API 调用返回一个包含用户信息的对象数组。
  • 此处的目的是从 API 收到的响应中提取名称列表。
const users = [
{
    'name': 'John Doe',
    'address': 'Wellington St, Ottawa, ON K1A 0A9'
},
{
    'name': 'Jane Doe',
    'address': '1600 Pennsylvania Ave NW, Washington, DC 20500'
},
{
    'name': 'Hannibal Lecter',
    address: '10800 97 Ave NW, Edmonton, AB T5K 2B6'
}]

const names = users.map(currentItem => {
    return currentItem['name']
})

// names = ['John Doe', 'Jane Doe', 'Hannibal Lecter']

筛选

  • 与该方法类似map(),该filter()方法允许您遍历数组的元素。
  • 不过,此案例的不同之处在于,它filter()返回的值能够通过所提供的某些测试用例。

基本示例

  • 这是MDN网页上提供的另一个关于该filter()方法的简单示例。
const numbers = [2, 4, 6, 11, 12, 33]

const evenNumbers = numbers.filter(x => x % 2 === 0)

// evenNumbers = [2, 4, 6, 12]

实际应用案例

  • 与前面的例子类似,这种情况是指 API 调用返回一个包含用户信息的对象。
  • 目标是从 API 返回的响应中提取居住在美国境外的用户的姓名。
  • 目标是从 API 返回的响应中提取居住在美国境外的用户的姓名。
const users = [
{
    'name': 'John Doe',
    'address': 'Wellington St, Ottawa, ON K1A 0A9',
    'country': 'Canada'
},
{
    'name': 'Jane Doe',
    'address': '1600 Pennsylvania Ave NW, Washington, DC 20500',
    'country': 'United States'

},
{
    'name': 'Hannibal Lecter',
    'address': '10800 97 Ave NW, Edmonton, AB T5K 2B6',
    'country': 'Canada'

}]

const expatriates = users.filter(currentItem => {
    return currentItem['country'] !== 'United States'
})

/* expatriates = [
{
    name: 'John Doe',
    address: 'Wellington St, Ottawa, ON K1A 0A9',
    country: 'Canada'
},
{
    name: 'Hannibal Lecter',
    address: '10800 97 Ave NW, Edmonton, AB T5K 2B6',
    country: 'Canada'
}]
*/
  • 如果我们想要获取一个只包含名称的数组,那么仅使用此代码片段是不够的。
  • 因此,基于我们之前对该map()方法的了解,我们需要再调用一次函数。
const expatriateNames = expatriates.map(currentValue => {
    return currentValue['name']
})

// expatriateNames = ['John Doe', 'Hannibal Lecter']

减少

  • 顾名思义,该reduce()方法接受一个包含多个值的数组,并将它们“简化”为一个单一的返回值。

句法

    array.reduce((accumulator, current) => {}, initialValue)

基本示例

  • 在这个例子中,我们试图遍历数组的元素并将它们相加。
const array = [1, 2, 3]

const result = array.reduce((previousValue, currentValue) => {
    return previousValue + currentValue
})

// result = 6

实际应用案例

  • 之前提供的实际用例filter()并不理想,因为我们不得不依赖两个不同的函数调用才能获得想要的结果。
  • 在这个实现中,我们的目标与之前相同,即从 API 收到的响应中提取居住在美国境外的用户的姓名列表。
  • 在这种情况下,我们可以将两个filter()方法map()调用合并为一个函数reduce()
const users = [
{
    'name': 'John Doe',
    'address': 'Wellington St, Ottawa, ON K1A 0A9',
    'country': 'Canada'
},
{
    'name': 'Jane Doe',
    'address': '1600 Pennsylvania Ave NW, Washington, DC 20500',
    'country': 'United States'

},
{
    'name': 'Hannibal Lecter',
    'address': '10800 97 Ave NW, Edmonton, AB T5K 2B6',
    'country': 'Canada'

}]

const expatriates = users.reduce((result, user) => {
    // filter() equivalent
    if (user['country'] === 'United States') {
        return result
    }

    // map() equivalent
    result.push(user['name'])
    return result
}, initialValue = [])
  • 在此实现中,我们不向累加器数组添加任何值,在本例中我们将其称为result,从而成功地过滤掉居住在美国境外的用户。
  • 接下来,一旦我们通过了初始if语句检查,我们就将用户名添加到accumulator数组中。
  • 需要注意的是,虽然 reduce 函数可以返回单个输出,但通过将初始值初始化为空数组,该返回值也可以是一个数组。
  • 也许,我最喜欢的解释reduce()将 视为accumulator前一个值。

鸣谢

文章来源:https://dev.to/man2006/map-filter-reduce-in-javascript-4g3l