1. 求和
const numbers: number[] = [1, 2, 3, 4, 5]; // 定义一个数字数组
const sum: number = numbers.reduce((acc, curr) => acc + curr, 0);
// 使用 reduce 方法计算数组中所有数字的和,acc 是累加器,从 0 开始,curr 是当前值
console.log(sum); // 输出: 15
计算过程
下面是 reduce 方法的执行过程:
- 初始值
acc为0。 - 第一次迭代:
acc=0+1(当前元素)=1 - 第二次迭代:
acc=1+2(当前元素)=3 - 第三次迭代:
acc=3+3(当前元素)=6 - 第四次迭代:
acc=6+4(当前元素)=10 - 第五次迭代:
acc=10+5(当前元素)=15
最终,reduce 方法返回的结果是 15,这个结果被赋值给 sum 变量。
2. 扁平化数组
const nestedArray: number[][] = [[1, 2], [3, 4], [5, 6]]; // 定义一个二维数组
const flattenedArray: number[] = nestedArray.reduce((acc, curr) => acc.concat(curr), []);
// 使用 reduce 方法将二维数组扁平化,acc 是累加器,初始值是空数组,curr 是当前数组
console.log(flattenedArray); // 输出: [1, 2, 3, 4, 5, 6]
计算过程
下面是 reduce 方法的执行过程:
- 初始值 acc 为 []。
- 第一次迭代:acc = [] + [1, 2](当前子数组)= [1, 2]
- 第二次迭代:acc = [1, 2] + [3, 4](当前子数组)= [1, 2, 3, 4]
- 第三次迭代:acc = [1, 2, 3, 4] + [5, 6](当前子数组)= [1, 2, 3, 4, 5, 6]
- 最终,reduce 方法返回的结果是 [1, 2, 3, 4, 5, 6],这个结果被赋值给 flattenedArray 变量。
3. 按照属性分组
interface Person {
name: string; // 定义人名属性
age: number; // 定义年龄属性
} //定义了一个 Person 接口,包含 name 和 age 两个属性,分别是字符串类型和数字类型。
const people: Person[] = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 },
{ name: 'Dave', age: 30 }
]; //定义了一个 Person 对象数组 people,其中包含四个人,每个人都有 name 和 age 属性。
const groupedByAge: { [key: number]: Person[] } = people.reduce((acc, curr) => {
if (!acc[curr.age]) { // 如果累加器对象 acc 中不存在当前年龄 curr.age
acc[curr.age] = []; // 为该年龄创建一个新的空数组acc[curr.age]。
}
acc[curr.age].push(curr); // 将当前 Person 对象 curr 添加到该年龄对应的数组中。
return acc; // 返回累加器对象
}, {}); // 初始值是一个空对象
console.log(groupedByAge);
/*
输出:
{
'25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
'30': [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }]
}
*/
计算过程
下面是 reduce 方法的执行过程:
第一次迭代
curr是{ name: 'Alice', age: 25 }acc是{}acc中没有25这个键,所以创建一个新数组:acc = { 25: [] }- 将
Alice添加到25对应的数组:acc = { 25: [{ name: 'Alice', age: 25 }] }
第二次迭代
curr是{ name: 'Bob', age: 30 }acc是{ 25: [{ name: 'Alice', age: 25 }] }acc中没有30这个键,所以创建一个新数组:acc = { 25: [{ name: 'Alice', age: 25 }], 30: [] }- 将
Bob添加到30对应的数组:acc = { 25: [{ name: 'Alice', age: 25 }], 30: [{ name: 'Bob', age: 30 }] }
第三次迭代
curr是{ name: 'Charlie', age: 25 }acc是{ 25: [{ name: 'Alice', age: 25 }], 30: [{ name: 'Bob', age: 30 }] }acc中已经有25这个键- 将
Charlie添加到25对应的数组:acc = { 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }], 30: [{ name: 'Bob', age: 30 }] }
第四次迭代
curr是{ name: 'Dave', age: 30 }acc是{ 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }], 30: [{ name: 'Bob', age: 30 }] }acc中已经有30这个键- 将
Dave添加到30对应的数组:acc = { 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }], 30: [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }] }
4. 创建查找映射 (Lookup Map)
interface Product {
id: number; // 定义产品ID属性
name: string; // 定义产品名称属性
price: number; // 定义产品价格属性
}//定义了一个 Product 接口和一个包含多个 Product 对象的数组。
const products: Product[] = [
{ id: 1, name: 'Laptop', price: 999 },
{ id: 2, name: 'Phone', price: 699 },
{ id: 3, name: 'Tablet', price: 499 },
]; // 定义一个包含多个产品的数组
const productMap: { [key: number]: Product } = products.reduce((acc, curr) => {
acc[curr.id] = curr; // 使用产品ID作为键,将产品对象存储在累加器对象中
return acc; // 返回累加器对象
}, {}); // 初始值是一个空对象
console.log(productMap);
/*
输出:
{
'1': { id: 1, name: 'Laptop', price: 999 },
'2': { id: 2, name: 'Phone', price: 699 },
'3': { id: 3, name: 'Tablet', price: 499 }
}
*/
// 通过ID访问产品
const laptop: Product = productMap[1];
console.log(laptop); // 输出: { id: 1, name: 'Laptop', price: 999 }
计算过程
下面是 reduce 方法的执行过程:
第一次迭代
curr是{ id: 1, name: 'Laptop', price: 999 }acc是{}- 使用
1作为键,将Laptop对象存储在acc中:acc = { 1: { id: 1, name: 'Laptop', price: 999 } }
第二次迭代
curr是{ id: 2, name: 'Phone', price: 699 }acc是{ 1: { id: 1, name: 'Laptop', price: 999 } }- 使用
2作为键,将Phone对象存储在acc中:acc = { 1: { id: 1, name: 'Laptop', price: 999 }, 2: { id: 2, name: 'Phone', price: 699 } }
第三次迭代
curr是{ id: 3, name: 'Tablet', price: 499 }acc是{ 1: { id: 1, name: 'Laptop', price: 999 }, 2: { id: 2, name: 'Phone', price: 699 } }- 使用
3作为键,将Tablet对象存储在acc中:acc = { 1: { id: 1, name: 'Laptop', price: 999 }, 2: { id: 2, name: 'Phone', price: 699 }, 3: { id: 3, name: 'Tablet', price: 499 } }
5. 统计元素出现次数
const fruits: string[] = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']; // 定义一个字符串数组
const fruitCounts: { [key: string]: number } = fruits.reduce((acc, curr) => {
acc[curr] = (acc[curr] || 0) + 1; // 如果当前水果在累加器对象中不存在,则设置为0,否则累加1
return acc; // 返回累加器对象
}, {}); // 初始值是一个空对象
console.log(fruitCounts);
/*
输出:
{
'apple': 3,
'banana': 2,
'orange': 1
}
*/
计算过程
下面是 reduce 方法的执行过程:
第一次迭代
curr是'apple'acc是{}acc['apple']为undefined,所以设置为0acc['apple'] = 0 + 1,结果为:acc = { 'apple': 1 }
第二次迭代
curr是'banana'acc是{ 'apple': 1 }acc['banana']为undefined,所以设置为0acc['banana'] = 0 + 1,结果为:acc = { 'apple': 1, 'banana': 1 }
第三次迭代
curr是'apple'acc是{ 'apple': 1, 'banana': 1 }acc['apple']已存在,值为1acc['apple'] = 1 + 1,结果为:acc = { 'apple': 2, 'banana': 1 }
第四次迭代
curr是'orange'acc是{ 'apple': 2, 'banana': 1 }acc['orange']为undefined,所以设置为0acc['orange'] = 0 + 1,结果为:acc = { 'apple': 2, 'banana': 1, 'orange': 1 }
第五次迭代
curr是'banana'acc是{ 'apple': 2, 'banana': 1, 'orange': 1 }acc['banana']已存在,值为1acc['banana'] = 1 + 1,结果为:acc = { 'apple': 2, 'banana': 2, 'orange': 1 }
第六次迭代
curr是'apple'acc是{ 'apple': 2, 'banana': 2, 'orange': 1 }acc['apple']已存在,值为2acc['apple'] = 2 + 1,结果为:acc = { 'apple': 3, 'banana': 2, 'orange': 1 }
6. 组合函数
const add5 = (x: number): number => x + 5; // 定义一个函数,输入值加5
const multiply3 = (x: number): number => x * 3; // 定义一个函数,输入值乘3
const subtract2 = (x: number): number => x - 2; // 定义一个函数,输入值减2
const composedFunctions: ((x: number) => number)[] = [add5, multiply3, subtract2]; // 定义一个函数数组
const result: number = composedFunctions.reduce((acc, curr) => curr(acc), 10);
// 使用 reduce 方法将函数依次应用到初始值 10 上,acc 是当前值,curr 是当前函数
console.log(result); // 输出: 43
计算过程
下面是 reduce 方法的执行过程:
初始化
composedFunctions: 一个包含三个函数的数组,这些函数依次是add5(加5),multiply3(乘以3),和subtract2(减去2)。- 初始值设为10,这个值将作为
reduce方法中的累加器(acc)的初始值。
第一次迭代
curr函数是add5acc(累加器) 的初始值是10- 当调用
add5(acc),将执行10 + 5,结果为15 - 累加器
acc更新为15
第二次迭代
curr函数是multiply3acc的当前值是15(上一步的结果)- 当调用
multiply3(acc),将执行15 * 3,结果为45 - 累加器
acc更新为45
第三次迭代
curr函数是subtract2acc的当前值是45(上一步的结果)- 当调用
subtract2(acc),将执行45 - 2,结果为43 - 累加器
acc最终更新为43
结束
reduce方法完成所有迭代后,最终返回值43赋值给result变量。- 使用
console.log(result)打印结果,即打印出了43。
7. 实现简单的类 Redux 状态管理
interface State {
count: number; // 定义计数器属性
todos: string[]; // 定义待办事项数组属性
}
interface Action {
type: string; // 定义动作类型属性
payload?: any; // 定义可选的负载属性
}
const initialState: State = {
count: 0,
todos: [],
}; // 定义初始状态
const actions: Action[] = [
{ type: 'INCREMENT_COUNT' },
{ type: 'ADD_TODO', payload: 'Learn Array.reduce()' },
{ type: 'INCREMENT_COUNT' },
{ type: 'ADD_TODO', payload: 'Master TypeScript' },
]; // 定义动作数组
const reducer = (state: State, action: Action): State => {
switch (action.type) {
case 'INCREMENT_COUNT':
return { ...state, count: state.count + 1 }; // 增加计数器
case 'ADD_TODO':
return { ...state, todos: [...state.todos, action.payload] }; // 添加待办事项
default:
return state; // 默认返回当前状态
}
};
const finalState: State = actions.reduce(reducer, initialState);
// 使用 reduce 方法将动作数组依次应用到初始状态上
console.log(finalState);
/*
输出:
{
count: 2,
todos: ['Learn Array.reduce()', 'Master TypeScript']
}
*/
计算过程
下面是 reduce 方法的执行过程:
初始化
initialState: 初始化状态,count为0,todos为空数组。actions: 一系列动作,包括增加计数器和添加待办事项。
第一次迭代
action是{ type: 'INCREMENT_COUNT' }state是{ count: 0, todos: [] }- 根据
action.type,执行增加计数器,更新后的状态为{ count: 1, todos: [] }
第二次迭代
action是{ type: 'ADD_TODO', payload: 'Learn Array.reduce()' }state是{ count: 1, todos: [] }- 根据
action.type,执行添加待办事项,更新后的状态为{ count: 1, todos: ['Learn Array.reduce()'] }
第三次迭代
action是{ type: 'INCREMENT_COUNT' }state是{ count: 1, todos: ['Learn Array.reduce()'] }- 根据
action.type,再次执行增加计数器,更新后的状态为{ count: 2, todos: ['Learn Array.reduce()'] }
第四次迭代
action是{ type: 'ADD_TODO', payload: 'Master TypeScript' }state是{ count: 2, todos: ['Learn Array.reduce()'] }- 根据
action.type,执行添加另一个待办事项,更新后的状态为{ count: 2, todos: ['Learn Array.reduce()', 'Master TypeScript'] }
8. 生成唯一值
const numbers: number[] = [1, 2, 3, 2, 4, 3, 5, 1, 6]; // 定义一个包含重复值的数字数组
const uniqueNumbers: number[] = numbers.reduce((acc, curr) => {
if (!acc.includes(curr)) { // 如果当前值不在累加器数组中
acc.push(curr); // 将当前值添加到累加器数组中
}
return acc; // 返回累加器数组
}, []); // 初始值是一个空数组
console.log(uniqueNumbers); // 输出: [1, 2, 3, 4, 5, 6]
9. 计算平均值
const grades: number[] = [85, 90, 92, 88, 95]; // 定义一个包含多个成绩的数字数组
const average: number = grades.reduce((acc, curr, index, array) => {
acc += curr; // 将当前值累加到累加器中
if (index === array.length - 1) { // 如果是数组的最后一个元素
return acc / array.length; // 计算累加器的平均值
}
return acc; // 返回累加器
}, 0); // 初始值是0
console.log(average); // 输出: 90
计算过程
下面是 reduce 方法的执行过程:
第一次迭代
-
curr是85 -
acc是0 -
acc += curr操作后acc变为85第二次迭代 -
curr是90 -
acc是85 -
acc += curr操作后acc变为175** 第三次迭代** -
curr是92 -
acc是175 -
acc += curr操作后acc变为267
第四次迭代
curr是88acc是267acc += curr操作后acc变为355
第五次(最后一次)迭代
curr是95acc是355acc += curr操作后acc变为450- 此时检测到是数组的最后一个元素(因
index === array.length - 1判断为真),执行acc / array.length计算平均值,得到450 / 5 = 90
结果
- 最终,
reduce方法返回的累加器值为90,这个值被赋给变量average。 - 当使用
console.log(average)打印输出时,显示的结果为90,代表这个成绩数组的平均值。