概述:
reduce()是ECMAScript为数组提供的归并方法,该方法会迭代数组的所有项,并构建一个最终返回值
- 接收参数: 一个函数、可选的归并起点值
- 第一个参数作为函数可以接收四个值: 上一个归并值、当前值、当前项的索引、数组本身
基本使用(取得数组各项的值并进行累加操作或阶乘):
const arr = [1, 2, 3, 4, 5, 3, 4, 5 ,6 ,7 , 7]
var sum = arr.reduce((pre, cur, index, array) => {
console.log(pre, cur, index);
return pre + cur
})
console.log(sum); //47,数组所有项的和,最后一项归并值
打印结果:
进阶用法
-
数组去重
思路:
- 设定初始归并值为空数组,用于接收去重后的数组;
- 将待去重的数组的每一项迭代【即cur】通过concat(cur)方法添加至副本【初始归并值pre】末尾
- 通过搜索方法includes()判断当前项是否存在于归并数组中,存在时,直接对归并值返回,反之,将当前迭代值通过concat()方法添加到数组末尾
const arr = [1, 2, 3, 4, 5, 3, 4, 5 ,6 ,7 , 7]
var sum2 = arr.reduce((pre, cur, index, arr) => {
if (!pre.includes(cur)) {
return pre.concat(cur)
}else {
return pre
}
}, [])
console.log(sum2);//[1, 2, 3, 4, 5, 6, 7]
-
统计数组相同项出现的次数
思路:
1.设定初始归并值为空对象,对象属性为数组项的值,对象属性值存放相同数组项出现的次数;
- 通过in操作符来判断以数组项值为名的属性是否存在于对象中,存在的话,将以该数组项值为属性名的属性值进行+1操作,否则,说明该数组项第一次出现,将代表出现次数的属性值设定为1
// 计算数组中每个元素出现的次数
const names = ['孙悟空', '猪八戒', '沙和尚', '唐僧', '孙悟空', '猪八戒']
let sum1 = names.reduce((pre, cur, index, array) => {
if ( cur in pre ) {
pre[cur]++
}else {
pre[cur] = 1
}
return pre
}, {})
console.log(sum1);//{孙悟空: 2, 猪八戒: 2, 沙和尚: 1, 唐僧: 1}
-
二维数组转为一维数组
const arr1 = [[1, 2], [2, 3], [4, 5]]
let arr_1 = arr1.reduce((pre, cur, index, arr) => {
pre = pre.concat(cur)
return pre
}, [])
console.log(arr_1);
-
操作对象
const books = [
{name: '解构现代化', price: 34, author: '温铁军'},
{name: '去依附', price: 26, author: '温铁军'},
{name: '八次危机', price: 30, author: '温铁军'},
{name: '百年孤独', price: 46, author: '加西亚.马尔克斯'},
{name: '霍乱时期的爱情', price: 28, author: '加西亚.马尔克斯'},
{name: '三体', price: 58, author: '刘慈欣'}
]
// 需求1--求所有书籍的总价格
var price_sum = books.reduce((pre, cur, index, array) => {
return pre += cur.price;
}, 0)
console.log(price_sum);
// 需求2--求温铁军的书籍的总价格
var wen_price_sum = books.reduce((pre, cur, index, array) => {
if (cur.author === '温铁军') {
pre += cur.price
}
return pre
}, 0)
console.log(wen_price_sum);
// 需求3--求温铁军书籍的平均价格
var wen_price_aver = books.reduce((pre, cur, index, array) => {
if (cur.author === '温铁军') {
pre.name = "温铁军",
pre.total += cur.price
pre.count ++
}
return pre
}, {name: '', total: 0, count: 0})
console.log(wen_price_aver);
console.log(wen_price_aver.total/wen_price_aver.count);
// 求所有作者书的平均价格
var all_price_aver = books.reduce((pre, cur, index, array) => {
// 当归并对象内不存在该属性时,对该属性进行初始化,纪录作者名、总量、出现次数
if (!pre[cur.author]) {
pre[cur.author] = {
name: cur.author,
total: 0,
count: 0
}
}
// 对价格进行累加操作
pre[cur.author].total += cur.price
// 用对象属性纪录当前项出现次数
pre[cur.author].count++
return pre
}, {})
console.log(all_price_aver);
var mylist = Object.values(all_price_aver)
console.log(mylist);
// 接收包含作者及价格平均值的对象
const obj = {}
// 遍历数组,将数组各需要项赋值给接收对象【作者名为属性名, 平均值为属性值】
var mysum = mylist.forEach((item) => {
console.log(item);
obj[item.name] = item.total/item.count
})
console.log(obj);//{温铁军: 30, 加西亚.马尔克斯: 37, 刘慈欣: 58}