javascript数组有哪些方法_如何使用map和filter进行数据转换?

map用于一对一转换并返回等长新数组,filter用于条件筛选并返回真值元素组成的新数组;二者均不修改原数组,常组合使用(先filter后map)以提升可读性与性能。

map 和 filter 是什么,它们最常用来做什么

mapfilter 都是 JavaScript 数组的原生方法,用于对数组元素做**不可变操作**:不修改原数组,而是返回一个新数组。map 适合「一对一转换」,比如把每个数字翻倍、把对象数组提取某个字段;filter 适合「条件筛选」,比如只保留大于 10 的数、只留下状态为 'active' 的用户。

map 的基本用法和容易踩的坑

map 接收一个回调函数,该函数会被调用 每次遍历一个元素时,并把返回值收集进新数组。它总是返回与原数组等长的新数组 —— 即使回调里写 return undefined 或没写 return,也会塞进 undefined

  • 回调函数默认接收三个参数:itemindexarray,但通常只用第一个
  • 不能跳过某项(不像 filter),想“跳过”得显式返回 undefinednull,但那仍占一个位置
  • 如果需要改变长度,别硬套 map,该用 filter 就用 filter,该用 flatMap 就用 flatMap
const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2); // [2, 4, 6]

const users = [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}]; const names = users.map(u => u.name); // ['Alice', 'Bob']

filter 的行为细节和常见误用

filter 同样接收一个回调函数,但它只把回调返回「真值」(truthy)的元素放进新数组。注意:返回 0''falsenullundefinedNaN 都算假值,对应元素会被过滤掉。

  • 回调函数也接收 itemindexarray 三个参数
  • 不要在 filter 回调里做副作用(比如发请求、改全局变量),它本意是纯函数式筛选
  • 想同时转换+筛选?别链式调用 map().filter()(性能差),

    优先考虑 flatMap 或一次循环手动构建
const scores = [85, 92, 76, 100, 54];
const passing = scores.filter(s => s >= 60); // [85, 92, 76, 100]

const items = [{done: true}, {done: false}, {done: true}]; const doneItems = items.filter(i => i.done); // [{done: true}, {done: true}]

map 和 filter 组合使用的典型场景

实际开发中,常先 filtermap:比如从用户列表中筛出管理员,再提取他们的邮箱。这种组合清晰、可读性强,且符合数据流直觉。

  • 顺序很重要:先 filtermap 能减少后续处理的数据量
  • 避免在 map 中嵌套条件逻辑来模拟 filter,那样会让语义模糊、难以测试
  • ESLint 会警告 map 中出现 if + return undefined 的模式,就是因为它违背了 map 的设计意图
const users = [
  {role: 'admin', email: 'a@ex.com'},
  {role: 'user', email: 'b@ex.com'},
  {role: 'admin', email: 'c@ex.com'}
];

const adminEmails = users .filter(u => u.role === 'admin') .map(u => u.email); // ['a@ex.com', 'c@ex.com']

真正难的不是记住语法,而是判断什么时候该用 map、什么时候该用 filter、什么时候两者都不够用——比如要扁平化嵌套数组、要按条件分组、要提前终止遍历,就得换别的方法或手写循环。