← 返回文章列表
JavaScript·2155 次阅读

数组方法全家桶:map、filter、reduce 到底怎么用

数组方法全家桶:map、filter、reduce 到底怎么用

刚开始学 JS 的时候什么都用 for 循环干,后来看别人代码全是 map、filter 链式调用,才明白数组方法是按"意图"分类的。选对方法,代码自己会说话。

变换:map

一对一变换,返回等长新数组:

const users = [{ name: '张三', age: 20 }, { name: '李四', age: 25 }]
const names = users.map((u) => u.name) // ['张三', '李四']

常见误用:用 map 只为了遍历执行副作用(比如里面发请求)。map 的返回值被丢掉就是选错了工具,纯遍历用 forEach 或 for...of。

筛选:filter

按条件保留元素,返回可能变短的新数组:

const adults = users.filter((u) => u.age >= 18)

配套的还有 find(返回第一个匹配的元素本身)、findIndex、some(是否存在)、every(是否全部满足)。需要"只找一个"就别 filter 再取 [0],find 语义更准还能提前结束。

聚合:reduce

reduce 是最强也最唬人的一个,把数组收敛成任意一个值:

const total = orders.reduce((sum, o) => sum + o.amount, 0)

// 分组
const byCategory = posts.reduce((acc, p) => {
  ;(acc[p.category] = acc[p.category] || []).push(p)
  return acc
}, {})

// 计数
const wordCount = words.reduce((acc, w) => {
  acc[w] = (acc[w] || 0) + 1
  return acc
}, {})

注意两点:永远传第二个参数(初始值),否则空数组直接抛错;回调里别漏 return acc。

链式组合

真正的威力在组合,从原始数据到目标结果一条管道:

const result = orders
  .filter((o) => o.status === 'paid')
  .map((o) => o.amount)
  .reduce((sum, n) => sum + n, 0)

可读性远超一个塞满中间变量的 for 循环。

其他高频方法速查

方法 干什么 返回值
slice 截取一段 新数组(不改原数组)
splice 删/插/替换 被删元素(改原数组)
concat 拼接 新数组
flat / flatMap 拍平嵌套数组 新数组
includes 是否包含 布尔(NaN 也能查到)
sort 排序 原数组(原地改)
join 拼成字符串 string

两个坑要记住:sort() 默认按字符串排([10, 9, 80].sort() 得到 [10, 80, 9]),数字排序必须传 (a, b) => a - b;sort 和 splice 会改原数组,Vue/React 的数据流里一不小心就踩坑。

小结

  • 变换用 map、筛选用 filter、收敛用 reduce、遍历用 for...of
  • 找一个用 find,判断存在用 some
  • 链式调用让数据处理变成一条清晰的管道
  • 分清哪些方法改原数组(sort/splice),哪些不改(map/filter/slice)

这些方法没有性能魔法,胜在语义明确。代码是写给人看的,顺便能在机器上跑。

看到这里了?如果这篇文章帮到过你

请我喝瓶可乐就好 🥤

收款码

评论0 条

还没有评论,来抢沙发~

发表评论

评论需审核后显示

© 2026 许冬博客 · 专注 JS 技术分享

·RSS 订阅·Powered by Nuxt 4