filter负责筛选、map负责转换,应先filter后map以提升性能与可读性;错误混用会导致undefined空洞或低效计算。

filter 和 map 各司其职:filter 负责“挑”,map 负责“改”。两者配合不是叠加功能,而是按数据流顺序组织操作——先筛后转,逻辑清晰、性能可控、代码易读。
先 filter 再 map 是更自然的链式顺序
多数场景下,应先用 filter 筛出目标子集,再用 map 对这些有效项做转换。这样避免对被排除的数据做无意义计算。
- ✅ 推荐写法:
users.filter(u => u.active).map(u => ({ id: u.id, name: u.name.trim() })) - ❌ 低效写法:
users.map(u => ({ id: u.id, name: u.name?.trim() })).filter(item => item.name)—— 即使用户不 active,也要执行 trim 和对象构造 - 小数组影响不大,但处理上万条数据时,先 filter 可减少 map 的调用次数,降低内存与 CPU 开销
filter 中注意属性存在性,避免误筛空值
filter 回调返回 falsy 值(undefined、null、0、'')就会把该项过滤掉。取对象字段时若字段缺失,极易踩坑。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- ❌ 危险写法:
data.filter(item => item.status === 'done')—— 若某 item 没有 status 属性,item.status是undefined,比较结果为false,该项被意外剔除 - ✅ 安全写法:
data.filter(item => item.status != null && item.status === 'done') - 或用可选链 + 显式判断:
data.filter(item => item?.status === 'done')(ES2020+)
map 里别混 filter 逻辑,否则结果含 undefined
map 的设计目标是等长映射。如果在 map 回调中加 if 判断却不给 else 分支,未满足条件的项会返回 undefined,导致新数组出现空洞。
立即学习“Java免费学习笔记(深入)”;
- ❌ 错误示范:
[1,2,3,4].map(x => { if (x % 2 === 0) return x * 2 })→ 结果是[undefined, 4, undefined, 8] - ✅ 正确拆分:
[1,2,3,4].filter(x => x % 2 === 0).map(x => x * 2)→[4, 8] - 想一步到位?可用 reduce,但要权衡可读性;日常开发优先选 filter + map 组合
需要去重+转换时,慎用 indexOf 实现 filter
常见写法 arr.filter((item, i) => arr.indexOf(item) === i) 表面简洁,实际是 O(n²) 时间复杂度,大数据量下极慢。
- ✅ 更高效替代:
[...new Set(arr)].map(transformFn)(适用于基础类型) - ✅ 对象数组去重:
arr.filter((item, i, a) => a.findIndex(obj => obj.id === item.id) === i).map(...),或先 reduce 构建 Map 去重再 map - 50 万条数据用 indexOf 去重可能卡顿数分钟;Set 或 Map 方案基本保持 O(n)

















