前置知识: JavaScript

数组高阶方法

00:00
1 min Intermediate 2026/6/14

JavaScript数组高阶方法详解:reduce、flatMap及函数式数组操作模式。

1. reduce — 万能归约

1.1 基本语法

array.reduce((accumulator, currentValue, index, array) => {
  return newAccumulator;
}, initialValue);

1.2 常见用法

求和/求积

const sum = [1, 2, 3, 4].reduce((acc, cur) => acc + cur, 0); // 10
const product = [1, 2, 3, 4].reduce((acc, cur) => acc * cur, 1); // 24

对象分组

const people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 25 },
];

const byAge = people.reduce((acc, person) => {
  const key = person.age;
  (acc[key] ??= []).push(person);
  return acc;
}, {});
// { 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
//   30: [{ name: 'Bob', age: 30 }] }

// 使用 Object.groupBy(ES2024)
const byAge2 = Object.groupBy(people, (p) => p.age);

数组扁平化

const nested = [[1, 2], [3, [4, 5]], [6]];
const flat = nested.reduce((acc, cur) => acc.concat(cur), []);
// [1, 2, 3, [4, 5], 6] — 只扁平一层

管道函数

const pipe =
  (...fns) =>
  (input) =>
    fns.reduce((acc, fn) => fn(acc), input);

const transform = pipe(
  (str) => str.trim(),
  (str) => str.toLowerCase(),
  (str) => str.replace(/\s+/g, '-')
);

transform('  Hello World  '); // 'hello-world'

统计词频

const words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple'];
const frequency = words.reduce((acc, word) => {
  acc[word] = (acc[word] || 0) + 1;
  return acc;
}, {});
// { apple: 3, banana: 2, cherry: 1 }

1.3 reduce 常见陷阱

忘记初始值

//  空数组没有初始值会报错
[].reduce((acc, cur) => acc + cur); // TypeError

//  始终提供初始值
[].reduce((acc, cur) => acc + cur, 0); // 0

修改累加器

//  修改原对象
const result = items.reduce((acc, item) => {
  acc.push(item.id); // 修改了 acc
  return acc;
}, []);

//  函数式风格(虽然 push 也可以,但更推荐不可变风格)
const result = items.reduce((acc, item) => [...acc, item.id], []);
// 注意:这种写法性能较差,大数据量时推荐用 push

2. flatMap — 映射后扁平化

2.1 基本语法

array.flatMap((element, index, array) => {
  return newArrayOrElement;
});

flatMap 等价map 后跟 flat(1)

arr.flatMap(fn) === arr.map(fn).flat(1);

2.2 常见用法

映射

const sentences = ['Hello World', 'Good Morning'];
const words = sentences.flatMap((s) => s.split(' '));
// ['Hello', 'World', 'Good', 'Morning']

过滤 + 映射

// 只保留正数并加倍
const numbers = [-2, -1, 0, 1, 2, 3];
const result = numbers.flatMap((n) => (n > 0 ? [n * 2] : []));
// [2, 4, 6]

提取嵌套属性

const users = [
  { name: 'Alice', orders: [{ id: 1 }, { id: 2 }] },
  { name: 'Bob', orders: [{ id: 3 }] },
  { name: 'Charlie', orders: [] },
];

const orderIds = users.flatMap((user) => user.orders.map((o) => o.id));
// [1, 2, 3]

展开结构

const categories = [
  { name: 'Electronics', subcategories: ['Phones', 'Laptops'] },
  { name: 'Clothing', subcategories: ['Shirts', 'Pants'] },
];

const allCategories = categories.flatMap((cat) => [cat.name, ...cat.subcategories]);
// ['Electronics', 'Phones', 'Laptops', 'Clothing', 'Shirts', 'Pants']

3. 其他高阶方法

3.1 find 和 findIndex

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
];

users.find((u) => u.id === 2); // { id: 2, name: 'Bob' }
users.findIndex((u) => u.id === 2); // 1
users.findLast((u) => u.name.startsWith('B')); // { id: 2, name: 'Bob' }
users.findLastIndex((u) => u.name.startsWith('B')); // 1

3.2 every 和 some

const ages = [18, 25, 30, 42];
ages.every((age) => age >= 18); // true — 全部满足
ages.some((age) => age > 40); // true — 至少一个满足

3.3 Array.from 的映射

// 创建范围数组
const range = Array.from({ length: 5 }, (_, i) => i * 2);
// [0, 2, 4, 6, 8]

// 去重
const unique = Array.from(new Set([1, 2, 2, 3, 3]));
// [1, 2, 3]

3.4 at() 方法

const arr = [10, 20, 30, 40, 50];
arr.at(0); // 10
arr.at(-1); // 50 — 负索引从末尾计数
arr.at(-2); // 40

4. 函数式组合

4.1 链式调用

const result = orders
  .filter((order) => order.status === 'completed')
  .map((order) => order.total)
  .reduce((sum, total) => sum + total, 0);

4.2 自定义组合

const compose =
  (...fns) =>
  (arr) =>
    fns.reduce((acc, fn) => fn(acc), arr);

const processNumbers = compose(
  (arr) => arr.filter((n) => n > 0),
  (arr) => arr.map((n) => n * 2),
  (arr) => arr.reduce((sum, n) => sum + n, 0)
);

processNumbers([-1, 2, -3, 4, 5]); // 22

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式