详解javascript的reduce()方法,各种场景

语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

参数:

1. function(total,currentValue, currentIndex,arr)  必需。用于执行每个数组元素的函数。

  • total 必需。初始值, 或者计算结束后的返回值。
  • currentValue 必需。当前元素。
  • currentIndex 可选。当前元素的索引。
  • arr 可选。当前元素所属的数组对象。

2. initialValue 可选。传递给函数的初始值

 如何使用?参考如下示例:

1. 实现累加,计算数组里所有值的和

let arr = [1, 2, 3, 4, 5]
let result = arr.reduce((total, currentValue, currentIndex, arr) => {
	console.log('total', total)
	console.log('currentValue', currentValue)
	console.log('currentIndex', currentIndex)
	console.log('arr', arr)
  // total 1
  // currentValue 2
  // currentIndex 1
  // arr [ 1, 2, 3, 4, 5 ]

  // total 3
  // currentValue 3
  // currentIndex 2
  // arr [ 1, 2, 3, 4, 5 ]

  // total 6
  // currentValue 4
  // currentIndex 3
  // arr [ 1, 2, 3, 4, 5 ]

  // total 10
  // currentValue 5
  // currentIndex 4
  // arr [ 1, 2, 3, 4, 5 ]
	return total + currentValue
})
console.log(result) // 15
let arr = [1, 2, 3, 4, 5]
let result = arr.reduce((total, currentValue, currentIndex, arr) => {
	console.log('total', total)
	console.log('currentValue', currentValue)
	console.log('currentIndex', currentIndex)
	console.log('arr', arr)
  // total 10
  // currentValue 1
  // currentIndex 0
  // arr [ 1, 2, 3, 4, 5 ]

  // total 11
  // currentValue 2
  // currentIndex 1
  // arr [ 1, 2, 3, 4, 5 ]

  // total 13
  // currentValue 3
  // currentIndex 2
  // arr [ 1, 2, 3, 4, 5 ]

  // total 16
  // currentValue 4
  // currentIndex 3
  // arr [ 1, 2, 3, 4, 5 ]

  // total 20
  // currentValue 5
  // currentIndex 4
  // arr [ 1, 2, 3, 4, 5 ]
	return total + currentValue
}, 10)
console.log(result) // 25

上面两个示例表示,如果没有设置初始值initialValue,那么第一次遍历时的total就是数组的第一项,函数会遍历执行 数组的长度 - 1 次。

如果有设置初始值initialValue,那么第一次遍历时的total就是初始值initialValue,函数会遍历执行 数组的长度 次。

如果有return 语句,第二次遍历时的 total 就是上一次return语句返回的值。如果没有return语句,total返回undefined(一般不会这样使用,都是有return语句的)

currentIndex是currentValue在数组中的下标值,arr是调用reduce()的数组

较为常用的就是前两个参数

2.  累加数组中对象的值

let arr = [
	{ name: 'yee', num: 666 },
	{ name: 'qian', num: 111 },
	{ name: 'li', num: 111 },
]
let result = arr.reduce((prev, next) => {
	return prev + next.num
}, 0)
console.log(result) // 888

3. 计算数组中每个元素出现的次数

let arr = ['mysql', 'oracle', 'oracle', 'mysql', 'oracle', 'oracle', 'oceanbase', 'goldendb', 'db2', 'mongodb', 'gbase']
let result = arr.reduce(function (prev, next) {
	prev[next] = prev[next] + 1 || 1
	return prev
}, {})
console.log(result);
// { mysql: 2, oracle: 4, oceanbase: 1, goldendb: 1, db2: 1, mongodb: 1, gbase: 1 }

4. 数组去重

let arr = [1, 2, 3, 3, 2, 1, null, null, undefined, true, false, NaN, false, true, undefined]
let result = arr.reduce((prev, next) => {
	return prev.includes(next) ? prev : prev.concat(next)
}, [])
console.log(result); // [ 1, 2, 3, null, undefined, true, false, NaN ]

5. 对象数组的去重,相比于第4点,这种实际使用情况更多

// 根据对象的id值去重
let arr = [
	{ id: 1, name: '张三' },
	{ id: 2, name: '李四' },
	{ id: 3, name: '王五' },
	{ id: 1, name: '张三' },
]
let result = arr.reduce((prev, next) => {
	const isExist = prev.some((item) => item.id === next.id)
	if (!isExist) {
		prev.push(next)
	}
	return prev
}, [])
console.log(result)
// [ { id: 1, name: '张三' }, { id: 2, name: '李四' }, { id: 3, name: '王五' } ]

6. 将多维数组转为一维数组

// 二维
let arr = [
	[1, 2, 3],
	[4, 5, 6],
	[7, 8, 9],
]
let result = arr.reduce((prev, next) => {
	return prev.concat(next)
}, [])
console.log(result)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

// 多维
let arr1 = [1, [2, [[3, 4], 5], 6, 7, [8, 9, [10, 11, [12, 13]]]]]
function splitArr(arr) {
	return arr.reduce((prev, next) => {
		return prev.concat(Array.isArray(next) ? splitArr(next) : next)
	}, [])
}
console.log(splitArr(arr1)) 
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
console.log(arr1.flat(Infinity)) 
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
// 另:使用ES6中的flat()方法也可以实现
// flat(n): n非必填项,n默认是1,表示扁平化深度。Infinity表示不管嵌套多少层。

7. 将对象数组,按照对象的某个属性值进行分类

let animals = [
	{ name: '小明', age: 6, type: 'dog' },
	{ name: '小芳', age: 18, type: 'person' },
	{ name: '小红', age: 6, type: 'cat' },
	{ name: '小野', age: 18, type: 'person' },
	{ name: '小雨', age: 6, type: 'dog' },
	{ name: '小龙', age: 18, type: 'person' },
	{ name: '滚滚', age: 8, type: 'dog' },
]

function classification(arr, attr) {
	if (!Array.isArray(arr)) {
		return []
	}
	return arr.reduce((prev, next) => {
		let obj = prev.find((item) => item.type == next.type)
		if (obj) {
			obj.list.push(next)
		} else {
			prev.push({
				[attr]: next[attr],
				list: [next],
			})
		}
		return prev
	}, [])
}
console.log(classification(animals, 'type'))
// [
//   {
//       "type": "dog",
//       "list": [
//           {
//               "name": "小明",
//               "age": 6,
//               "type": "dog"
//           },
//           {
//               "name": "小雨",
//               "age": 6,
//               "type": "dog"
//           },
//           {
//               "name": "滚滚",
//               "age": 8,
//               "type": "dog"
//           }
//       ]
//   },
//   {
//       "type": "person",
//       "list": [
//           {
//               "name": "小芳",
//               "age": 18,
//               "type": "person"
//           },
//           {
//               "name": "小野",
//               "age": 18,
//               "type": "person"
//           },
//           {
//               "name": "小龙",
//               "age": 18,
//               "type": "person"
//           }
//       ]
//   },
//   {
//       "type": "cat",
//       "list": [
//           {
//               "name": "小红",
//               "age": 6,
//               "type": "cat"
//           }
//       ]
//   }
// ]

除了上述场景,reduce() 方法还可以用于更复杂的数据处理和转换操作。它提供了一种灵活且强大的方式来处理数组中的元素,并生成最终的结果。根据具体的需求,你可以灵活运用 reduce() 方法来解决各种数组操作的问题。

 如果帮助到您了,可以留下一个赞👍告诉我  

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿小野

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值