理解 JavaScript 中的 map()、filter() 和 reduce()

2025-06-07

理解 JavaScript 中的 map()、filter() 和 reduce()

目录

  1. 介绍
  2. 地图()
  3. 筛选()
  4. 减少()
  5. 资源

介绍

在上一篇文章中,我们讨论了“一等函数”以及 JavaScript 如何将函数视为一等公民。

Higher Orders Functions函数式是指接受一个或多个函数作为参数,并且/或者返回一个函数的函数。这个概念源于函数式编程。JavaScript 是一种大量使用函数式编程概念的语言,Higher-Order Functions也是其中之一。

在这篇文章中,我们将讨论map()filter()以及reduce()一些最著名和最易于使用的高阶函数。

什么是地图?

该方法通过对调用数组中的每个元素调用提供的函数map()来创建一个新数组

假设我们要创建一个包含数字数组的双精度值的新数组。

一种方法是创建函数 double 并对 forEach 中的每个元素调用它。

使用 forEach 编写的 Map

const numbers = [1, 2, 3];
const result = [];

const double = (number) => {
    return number * 2;
};

// Iterate over an array
numbers.forEach((number) => {
  result.push(double(number)); 
})

// [2 4 6]
console.log(result);
Enter fullscreen mode Exit fullscreen mode

这就是map发挥作用的地方!我们不需要手动调用函数,而是可以将函数传递给 map,JavaScript 会在每个元素上为我们调用该函数!

不使用 forEach 编写的 Map

const numbers = [1, 2, 3];

const double = (number) => {
  return number * 2;
};

const result = numbers.map(double);

//[2,4,6]
console.log(result);
Enter fullscreen mode Exit fullscreen mode

现在让我们看一些可以使用 map 的其他示例

在下面的例子中,我们使用 map 创建一个包含每个人全名的新数组。

const people = [{
    first_name: "Michael",
    last_name: "Jordan"
}, {
    first_name: "LeBron",
    last_name: "James"
}, {
    first_name: "Stephen",
    last_name: "Curry"
}];

const fullNames = people.map((person) => {
    return `${person.first_name} ${person.last_name}`;
});

// [ 'Michael Jordan', 'LeBron James', 'Stephen Curry' ]
console.log(fullNames);
Enter fullscreen mode Exit fullscreen mode

在下面的例子中,我们创建了一个包含每天前两个字母的新数组。

const days = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
];

const newDays = days.map((day) => {
    return day.substring(0,2);
});

// [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ]
console.log(newDays);
Enter fullscreen mode Exit fullscreen mode

什么时候应该使用地图?

  1. 当你想要创建一个与原始数组长度相同的新数组时。
  2. 当你想将一个事物的数组转换为另一个事物的数组时。

什么是过滤器?

filter()方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

  • 调用filter()将返回一个新数组。
  • 使用的回调函数filter应该返回truefalse
    • true当前元素是否应该出现在新数组中。
    • false如果当前元素不应该出现在新数组中。

假设我们要创建一个包含数字数组的偶数的新数组。

一种方法是创建函数 isEven 来检查数字是否为偶数,并对 forEach 中的每个元素调用它。

使用 forEach 编写的过滤器

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = [];

const isEven = (number) => {
    return number % 2 === 0;
  };

// 2. Iterate over an array
numbers.forEach((number) => {
  if (isEven(number)) {
    evenNumbers.push(number);
  }
});

// [ 2, 4, 6, 8, 10 ]
console.log(evenNumbers);
Enter fullscreen mode Exit fullscreen mode

不使用 forEach 编写的过滤器

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const isEven = (number) => {
  return number % 2 === 0;
};

const evenNumbers = numbers.filter(isEven);

// [ 2, 4, 6, 8, 10 ]
console.log(evenNumbers);
Enter fullscreen mode Exit fullscreen mode



现在让我们看一些其他可以使用过滤器的例子

在下面的例子中,我们创建了一个新数组,其中包含名字不超过六个字符的人。

const people = [{
    first_name: "Michael",
    last_name: "Jordan"
}, {
    first_name: "LeBron",
    last_name: "James"
}, {
    first_name: "Stephen",
    last_name: "Curry"
}];


const short = people.filter((person) => {
    return person.first_name.length <= 6;
});

// [ { first_name: 'LeBron', last_name: 'James' } ]
console.log(short);
Enter fullscreen mode Exit fullscreen mode

在下面的例子中,我们有一个包含每周天数的数组,我们想要创建一个新数组,该数组仅包含字母数量小于 7 的天数。

const days = [
  'Sunday',
  'Monday',
  'Tuesday',
  'Wednesday',
  'Thursday',
  'Friday',
  'Saturday'
];
// create a new array with only the days that the length of their characters is less than 7
const shortDays = days.filter(day => {
  return day.length < 7;
});

// [ 'Sunday', 'Monday', 'Friday' ]
console.log(shortDays);
Enter fullscreen mode Exit fullscreen mode

何时使用过滤器:

  • 当您想要一个不同长度的新数组时,基于数组中只有某些元素满足的某些条件。

什么是 Reduce?

reduce()方法将一个函数应用于累加器和数组中的每个元素(从左到右),以将其缩减为单个值。累加器可以是任何类型(整数、字符串、对象等),并且必须在调用 reduce() 时实例化或传递。

  • 调用reduce()将返回单个值。
  • 使用的回调函数reduce将传递累加器值和数组中的元素。
    • 累加器值是上次调用回调函数返回的值。
    • 回调函数应该始终返回一个值以供下次回调使用。
  • 该函数的第三个参数reduce()是累加器的起始值。

假设我们要计算数字数组的总和。

使用 forEach 编写的 Reduce

const numbers = [1,2,3,4,5,6];
let sum = 0;

// Iterate over the array
numbers.forEach((number) => {
    sum +=  number;
});

// 21
console.log(sum);
Enter fullscreen mode Exit fullscreen mode

不使用 forEach 编写的 Reduce

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

// Iterate over the array
const sum = numbers.reduce((sum, number) => {
    sum += number;
    return sum; // Return the accumulator
}, 0);  // Initialize accumulator variable

// 21
console.log(sum);
Enter fullscreen mode Exit fullscreen mode

现在让我们看一些我们可以使用 reduce 的其他示例。

在下面的例子中,我们创建了一个新对象,其中包含股票名称作为键,以及股票频率作为值。

const stocks = ['TSLA', 'PLTR', 'TSLA', 'AAPL', 'PLTR', 'TSLA'];

const result = stocks.reduce((stockFreq, stock) => {
    if(stockFreq.hasOwnProperty(stock)) {
        stockFreq[stock]++;
    } else {
        stockFreq[stock] = 1;
    }

    return stockFreq;
}, {});

// { TSLA: 3, PLTR: 2, AAPL: 1 }
console.log(result);
Enter fullscreen mode Exit fullscreen mode

在下面的例子中,我们创建了一个包含每天前两个字母的新字符串。

const days = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
];

const newDay = days.reduce((buffer ,day) => {
    buffer += day.substring(0,2);
    return buffer;
}, "");

// SuMoTuWeThFrSa
console.log(newDay);
Enter fullscreen mode Exit fullscreen mode

资源

文章来源:https://dev.to/zagaris/understanding-map-filter-and-reduce-in-javascript-293i
PREV
每个 React 开发人员都应该知道的 5 个有用软件包
NEXT
从头开始实现 JavaScript 数组方法