万物皆可Reduce

Reduce的五彩世界

js知识

先来一段代码看看:

1
2
3
4
5
6
// 最简单的reduce例子: 数组求和
const array = [1, 2, 3, 4];
const sum = array.reduce((accumulator, currentValue) => {
return accumulator + currentValue
})
console.log(sum) // 数组的总和是:10

学习一个API前,我们需要API的功能和作用,再谈使用。

[简介] Array.reduce() 接收一个函数作为累加器 数组中的每个值(从左到右)开始缩减,最终返回函数。

1
2
3
4
array.reduce(function callback(accumulator, currentValue, index, array) {
// 返回执行某逻辑的结果,做为下一个accumulator的值
// 返回值可以是:object、array、string、number等等..reduce灵活的根本!!
}, [initialValue])

此方法接受两个参数:

  • callback(…) (必须)(接受4个参数:)

    • accumulator (初始值、或者通过计算结束后的返回值)
    • currentValue (当前元素值)
    • currentIndex (当前元素索引)
    • sourceArray (源数组)
  • initialValue (可选)

    • 如果不传默认值,第一次执行callback函数的时候会从数组索引1的地方开始、accumulator的值为数组的第一个值
    • 如果传了,则从数组索引0开始、accumulato的值为默认的值
    • 如果没有默认值、且数组是空的、则会报错!!
    • 初始化的值建议还是要传递、reduce灵活变化的根本
  • 注意:

    • reduce() 对于空数组是不会执行回调函数
    • reduce() 如果在没有初始值的空数组上执行则会报错!!!
    • reduce() 不会改变原数组

通过一个简单的案例让我们见识一下 reduce 的强大~
题目: 数组对象: 去重id,去除空评论,返回数据用户ID数组

1
2
3
4
5
6
7
8
9
10
11
12
let user = [
{id: 1, content: '吱吱吱'},
{id: 2, content: ''},
{id: 2, content: ''},
{id: 3, content: '智智智'},
{id: 3, content: '宏宏宏'},
{id: 3, content: '伟伟伟'},
{id: 4, content: '滴滴滴'},
{id: 5, content: '呃呃呃'},
{id: 6, content: '哒哒哒'},
{id: 7, content: '咚咚咚'},
]

常见做法:

1
2
3
// 简单~ 这样不是挺香吗?:(ps:只是举例、还有很多其他方式~)
Array.from(new Set(user.filter(e => e.content).map(e => e.id)))
// [1, 3, 4, 5, 6, 7]

使用reduce:

1
2
3
4
5
6
user.reduce((accumulator, value) => {
const id = value.id
return id && !accumulator.includes(id) ? [...accumulator, value.id] : accumulator
}, [])
// [1, 3, 4, 5, 6, 7]
// 是不是不用 map filter from Set...这些操作了呢?

reduce的替身术:

reduce替换map

1
2
3
4
5
6
const arr = [{name:'Amy', age: 10}, {name:'Bob', age: 20}]
// map用法
arr.map(itme => itme.name) // ["Amy", "Bob"]

// 利用扩展运算符 与默认参数
arr.reduce((total, value) => [...total, value.name], []) // ["Amy", "Bob"]

reduce替换filter

1
2
3
4
5
6
7
8
const arr = [{name:'Amy'}, {name:'Bob'}]
// filter用法
arr.filter(itme => itme.name === 'Amy')
// [{name: "Amy"}]

// 利用三元表达式、如果是真扩展的方式返回、如果是假不处理返回原来的值
arr.reduce((total, value) => value.name === 'Amy' ? [...total, value] : total, [])
// [{name: "Amy"}]

reduce 替代 map + filter

1
2
3
4
5
6
const arr = [{name:'Amy', age: '18'}, {name:'LaLa', age: '18'}, {name:'Bob', age: '22'}]
// filter + map 用法
arr.filter(item => item.age === '18').map(item => item.name)

// 利用扩展运算符 与默认参数
arr.reduce((total, value) => value.age === '18' ? [...total, value.name] : total, [])

reduce替换some

1
2
3
4
const arr = [{name:'Amy', age:18}, {name:'Bob', age:20}]

// some 当有一个满足条件就是true
arr.reduce((total, value) => total || value.age > 18, false)

reduce替换every

1
2
3
4
const arr = [{name:'Amy', age:18}, {name:'Bob', age:20}]

// every 当所有的条件都满足的时候才返回true
arr.reduce((total, value) => total && value.age > 18, true)

reduce替换flat方法

1
2
3
4
5
6
7
8
9
10
// 简化版:
var arr = [1, 2, 3, 4, [1, 2, 3, 4, 5, [2, 3, 4]]]

function arrFlat(data) {
return data.reduce((total, value) => {
return Array.isArray(value) ? [...total, ...arrFlat(value)] : [...total, value]
}, [])
}
arrFlat(arr)
// (12) [1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4]

reduce数组去重

1
2
3
4
const arr = ['a', 'a', 'b', 'b', 'c', 'c', 'd']

arr.reduce((total, value) => total.includes(value) ? total : [...total, value], [])
// (4) ["a", "b", "c", "d"]

合理的运用reduce,你会有意想不到的效果,但是还是结合自身逻辑使用,不可强用^_^,合适最重要!

文章目录
  1. 1. Reduce的五彩世界
    1. 1.1. js知识
      1. 1.1.1. reduce的替身术:
,