1. 求和
typescript
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. 扁平化数组
typescript
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. 按照属性分组
typescript
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)
typescript
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. 统计元素出现次数
typescript
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
,所以设置为0
acc['apple'] = 0 + 1
,结果为:acc = { 'apple': 1 }
第二次迭代
curr
是'banana'
acc
是{ 'apple': 1 }
acc['banana']
为undefined
,所以设置为0
acc['banana'] = 0 + 1
,结果为:acc = { 'apple': 1, 'banana': 1 }
第三次迭代
curr
是'apple'
acc
是{ 'apple': 1, 'banana': 1 }
acc['apple']
已存在,值为1
acc['apple'] = 1 + 1
,结果为:acc = { 'apple': 2, 'banana': 1 }
第四次迭代
curr
是'orange'
acc
是{ 'apple': 2, 'banana': 1 }
acc['orange']
为undefined
,所以设置为0
acc['orange'] = 0 + 1
,结果为:acc = { 'apple': 2, 'banana': 1, 'orange': 1 }
第五次迭代
curr
是'banana'
acc
是{ 'apple': 2, 'banana': 1, 'orange': 1 }
acc['banana']
已存在,值为1
acc['banana'] = 1 + 1
,结果为:acc = { 'apple': 2, 'banana': 2, 'orange': 1 }
第六次迭代
curr
是'apple'
acc
是{ 'apple': 2, 'banana': 2, 'orange': 1 }
acc['apple']
已存在,值为2
acc['apple'] = 2 + 1
,结果为:acc = { 'apple': 3, 'banana': 2, 'orange': 1 }
6. 组合函数
typescript
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
函数是add5
acc
(累加器) 的初始值是10
- 当调用
add5(acc)
,将执行10 + 5
,结果为15
- 累加器
acc
更新为15
第二次迭代
curr
函数是multiply3
acc
的当前值是15
(上一步的结果)- 当调用
multiply3(acc)
,将执行15 * 3
,结果为45
- 累加器
acc
更新为45
第三次迭代
curr
函数是subtract2
acc
的当前值是45
(上一步的结果)- 当调用
subtract2(acc)
,将执行45 - 2
,结果为43
- 累加器
acc
最终更新为43
结束
reduce
方法完成所有迭代后,最终返回值43
赋值给result
变量。- 使用
console.log(result)
打印结果,即打印出了43
。
7. 实现简单的类 Redux 状态管理
typescript
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. 生成唯一值
typescript
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. 计算平均值
typescript
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
是88
acc
是267
acc += curr
操作后acc
变为355
第五次(最后一次)迭代
curr
是95
acc
是355
acc += curr
操作后acc
变为450
- 此时检测到是数组的最后一个元素(因
index === array.length - 1
判断为真),执行acc / array.length
计算平均值,得到450 / 5 = 90
结果
- 最终,
reduce
方法返回的累加器值为90
,这个值被赋给变量average
。 - 当使用
console.log(average)
打印输出时,显示的结果为90
,代表这个成绩数组的平均值。