.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() 方法的作用:

  1. ✅ 映射+扁平化:一次性完成两个操作
  2. ✅ 高效简洁:避免中间数组,性能更好
  3. ✅ 一级扁平化:默认扁平化一级深度
  4. ✅ 过滤功能:返回空数组可过滤元素
  5. ✅ 实用场景:数据处理、转换、重组