.flatMap() 方法详解
📋 基本定义
.flatMap() 是 JavaScript 数组的映射+扁平化方法,先映射每个元素,然后扁平化结果数组。
🎯 一句话理解
先 map(映射),再 flat(扁平化)一级深度
💡 语法
// 1. 基本语法
const newArray = array.flatMap(callback)
// 2. 带 thisArg
const newArray = array.flatMap(callback, thisArg)
🔧 与 map + flat 的对比
// 使用 .flatMap()
const result1 = arr.flatMap(x => [x, x * 2])
// 等价于
const result2 = arr.map(x => [x, x * 2]).flat()
// 等价于
const result3 = [].concat(...arr.map(x => [x, x * 2]))
📊 基本示例
1. 简单的扁平化映射
// 将每个数字扩展为 [n, n*2]
const numbers = [1, 2, 3]
const result = numbers.flatMap(n => [n, n * 2])
console.log(result) // [1, 2, 2, 4, 3, 6]
// 对比:如果用 map
numbers.map(n => [n, n * 2]) // [[1, 2], [2, 4], [3, 6]]
2. 过滤并映射
// 过滤 0 并扩展
const arr = [1, 2, 3, 0, 4, 5]
const result = arr.flatMap(n => n === 0 ? [] : [n])
console.log(result) // [1, 2, 3, 4, 5] // 过滤掉了 0
🔄 与 map 的详细对比
| 场景 | map 结果 | flatMap 结果 |
|---|---|---|
| 简单映射 | [[1], [2], [3]] |
[1, 2, 3] |
| 扩展映射 | [[1,2], [2,4], [3,6]] |
[1, 2, 2, 4, 3, 6] |
| 条件映射 | [[1], [], [3]] |
[1, 3] |
// 示例
const arr = [1, 2, 3]
// map: 每个元素映射为一个数组
arr.map(x => [x, x * 2]) // [[1,2], [2,4], [3,6]]
// flatMap: 映射后扁平化
arr.flatMap(x => [x, x * 2]) // [1,2,2,4,3,6]
📈 高级用法
1. 字符串分割和扁平化
// 拆分句子中的单词
const sentences = ['Hello world', 'How are you']
const words = sentences.flatMap(sentence => sentence.split(' '))
console.log(words) // ['Hello', 'world', 'How', 'are', 'you']
2. 数据重组
// 订单和商品数据重组
const orders = [
{ orderId: 1, items: [{ name: 'A', price: 10 }, { name: 'B', price: 20 }] },
{ orderId: 2, items: [{ name: 'C', price: 30 }] }
]
// 获取所有商品
const allItems = orders.flatMap(order =>
order.items.map(item => ({
...item,
orderId: order.orderId
}))
)
console.log(allItems)
// [
// { name: 'A', price: 10, orderId: 1 },
// { name: 'B', price: 20, orderId: 1 },
// { name: 'C', price: 30, orderId: 2 }
// ]
3. 矩阵转置(二维数组处理)
// 二维数组处理
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
// 获取对角线元素
const diagonal = matrix.flatMap((row, index) =>
row[index] ? [row[index]] : []
)
console.log(diagonal) // [1, 5, 9]
⚡ 性能优势
1. 一次遍历完成
// 传统方法:两次遍历
const result1 = arr.map(x => doSomething(x)).flat()
// flatMap:一次遍历
const result2 = arr.flatMap(x => doSomething(x))
2. 避免中间数组
// flatMap 不创建中间数组
// 更高效,内存更友好
💡 注意事项
1. 只能扁平化一级
// flatMap 只扁平化一级
const arr = [1, 2, 3]
arr.flatMap(x => [[x, x * 2]]) // [[1, 2], [2, 4], [3, 6]] 只扁平化一层
2. 与 flat(1) 的区别
// flatMap 等价于 map 后接 flat(1)
arr.flatMap(x => doSomething(x))
// 等价于
arr.map(x => doSomething(x)).flat(1)
3. 返回空数组过滤元素
// 技巧:返回 [] 可以过滤元素
const arr = [1, 2, 3, 4, 5]
const evens = arr.flatMap(x => x % 2 === 0 ? [x] : [])
console.log(evens) // [2, 4] // 过滤掉了奇数
📋 总结
.flatMap() 方法的作用:
- ✅ 映射+扁平化:一次性完成两个操作
- ✅ 高效简洁:避免中间数组,性能更好
- ✅ 一级扁平化:默认扁平化一级深度
- ✅ 过滤功能:返回空数组可过滤元素
- ✅ 实用场景:数据处理、转换、重组
