javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS数组高阶函数filter、map与reduce

JavaScript数组高阶函数之filter、map与reduce详解

作者:Sunny.221

高阶函数可以帮助你增强你的JavaScript,让你的代码更具有声明性,简单来说,就是简单,简练,可读,这篇文章主要介绍了JavaScript数组高阶函数之filter、map与reduce的相关资料,需要的朋友可以参考下

1. 函数式编程简介

在JavaScript编程中,数组迭代是一项基础而重要的任务。随着函数式编程范式的普及,JavaScript提供了一系列强大的数组高阶函数,其中map、filter和reduce是最为核心和常用的三个方法。与传统的命令式编程(如for循环)相比,这些高阶函数采用声明式编程风格,使代码更加简洁、可读和易于维护。

函数式编程的核心思想是将函数作为第一公民,即函数可以像其他数据类型一样被传递、赋值和返回。这种编程范式与面向对象编程形成鲜明对比,它更注重数据的转换而非状态的改变。在JavaScript中,数组高阶函数正是这种思想的完美体现。

函数式编程是一种以函数为第一公民的编程范式,与命令式编程和面向对象编程形成对比。在 JavaScript 中,数组的高阶函数 filter、map 和 reduce 是函数式编程的典型代表,它们可

以使代码更加简洁、易读和可维护。

2. JavaScript数组迭代基础

在深入探讨高阶函数之前,我们先简要回顾JavaScript中数组迭代的基础方法。

2.1 传统迭代方法

for循环是最基础的迭代方法,通过索引访问数组的每个元素:

let array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]); // 输出数组中的每个元素
}

forEach方法是ES5引入的更简洁的遍历方式:

let array = [1, 2, 3, 4, 5];
array.forEach(function(item) {
  console.log(item); // 输出数组中的每个元素
});

for...of循环是ES6引入的语法,直接迭代数组的元素:

let array = [1, 2, 3, 4, 5];
for (let item of array) {
  console.log(item); // 输出数组中的每个元素
}

虽然这些方法都能实现数组迭代,但它们各有优缺点。for循环灵活但代码冗长;forEach简洁但无法中断遍历;for...of语法简洁但兼容性需要考虑。

2.2 高阶函数的优势

与上述方法相比,map、filter和reduce等高阶函数具有以下显著优势:

  1. 声明式编程:关注"做什么"而非"怎么做",代码更易理解

  2. 不可变性:不会修改原数组,而是返回新数组,符合函数式编程原则

  3. 链式调用:可以轻松组合多个操作,形成清晰的数据处理管道

  4. 代码复用:将通用逻辑抽象为函数,提高代码的可维护性

3. filter 函数:数组过滤

基本概念

filter 函数用于创建一个新数组,包含通过指定函数测试的所有元素。它不会改变原始数组,而是返回一个新的过滤后的数组。

语法结构

let newArray = arr.filter(function(currentValue[, index[, array]]) {
  // 返回 true 保留元素,false 过滤元素
}[, thisArg])

核心特性

使用示例

const nums = [10, 20, 111, 222, 444, 40, 50]
let newNums = nums.filter(function(n) {
  return n < 100
})
// 结果: [10, 20, 40, 50]

箭头函数简化

let newNums = nums.filter(n => n < 100)

4. map 函数:数组映射

基本概念

map 函数创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后的返回值。它不会改变原数组,而是返回一个新数组。

语法结构

let newArray = arr.map(function(currentValue[, index[, array]]) {
  // 返回新元素值
}[, thisArg])

核心特性

使用示例

let new2Nums = newNums.map(function(n) {
  return n * 2
})
// 结果: [20, 40, 80, 100]

箭头函数简化

let new2Nums = newNums.map(n => n * 2)

5. reduce 函数:数组汇总

基本概念

reduce 函数对数组中的每个元素执行一个由您提供的 reducer 函数,将其结果汇总为单个返回值。它是处理数组汇总操作的强大工具。

语法结构

let result = arr.reduce(function(accumulator, currentValue[, index[, array]]) {
  // 返回新的累加器值
}[, initialValue])

核心特性

使用示例

let total = new2Nums.reduce(function(preValue, n) {
  return preValue + n
}, 0)
// 结果: 240

箭头函数简化

let total = new2Nums.reduce((pre, n) => pre + n, 0)

6. 链式调用:组合使用

这三个方法的真正威力在于可以将它们链式调用,创建出高效且表达性强的数据处理流程。

链式调用的开销:每个方法都会生成新数组,处理大规模数据时可能影响性能。此时可考虑使用 for循环合并操作。

完整示例

// 分开调用
let total = nums.filter(n => n < 100)
               .map(n => n * 2)
               .reduce((pre, n) => pre + n, 0)

// 单行简洁写法
let total = nums.filter(n => n < 100).map(n => n * 2).reduce((pre, n) => pre + n)

复杂数据处理示例

// 处理对象数组的复杂案例
let users = [
  { name: 'Alice', age: 22 },
  { name: 'Bob', age: 17 },
  { name: 'Charlie', age: 30 }
]

let totalAge = users.filter(user => user.age > 18)
                   .map(user => user.age)
                   .reduce((sum, age) => sum + age, 0)
// 结果: 52

7. 三种方法对比总结

方法

返回类型

是否修改原数组

主要用途

filter

新数组

过滤数组中符合条件的元素

map

新数组

转换数组中的每个元素

reduce

任意类型(单个值)

将数组聚合为一个值

8. 性能考虑与优化建议

虽然这些高阶函数提供了声明式和简洁的数组处理方式,但在处理大型数据集时,它们的性能可能不如传统的 for 循环。这是因为高阶函数在内部会进行循环迭代,但额外的函数调用和上下文切换可能会引入额外开销。

优化建议

9. 实际应用场景

数据处理管道

let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let result = data.filter(num => num % 2 === 0)    // 筛选偶数
                 .map(num => num * 2)            // 乘以2
                 .filter(num => num > 5)          // 筛选大于5的数
                 .reduce((sum, num) => sum + num, 0) // 求和
// 结果: 24

数组去重

let arr = [1, 2, 2, 3, 4, 4, 5]
let uniqueArr = arr.filter((value, index, self) => {
  return self.indexOf(value) === index
})
// 结果: [1, 2, 3, 4, 5]

这些数组高阶函数是现代 JavaScript 开发中的重要工具,掌握它们能够帮助你写出更简洁、优雅和可维护的代码。

到此这篇关于JavaScript数组高阶函数之filter、map与reduce详解的文章就介绍到这了,更多相关JS数组高阶函数filter、map与reduce内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文