前言
最近读《JavaScript高级程序设计》,里面有一章介绍数组类型,有一个方法是之前没怎么见过,也是我没有系统的掌握,发现这个方法大有可用,还有可能提高你编程的B格,所以就记录下来
书里面的内容介绍
可以看到函数的兼容性还是很好的。
先介绍一下参数,reduce和reduceRight都接受两个参数,一个是函数,一个可选参数,只是一个从左遍历,一个从右
arr.reduce(callback,[initialValue])
那个这个callback又能接受4个参数,都为可选
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
返回值:第一个参数->也就是函数,返回的任何值都会作为第一个参数传给下一项(previousValue),这个过程会把数组的每一项都遍历,最后函数的返回直作为reduce的返回值
解释:如果有第二个参数initialValue,则initialValue作为函数的第一个参数previousValue,如果没有,则数组的第一项[0]作为previousValue,第二项[0],作为currentValue,也就是说当没有第二个参数时,数组遍历length-1次,因为从第二项开始。
书中给出一个实例 求和,我之前的求和就是for循环累加,但是书里面的写法好像逼格更高了一点,但写程序不能纯装逼,我们来看看还能有什么其他用法。
简单的示例
求和
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);// 第一次 (1, 2, 1),第二次 (3, 3, 2),第三次 (6, 4, 3)
return prev + cur;
})
console.log(arr, sum);// [1, 2, 3, 4],10
设置一个初始值0
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);// 第一次 (0, 1, 0),第二次 (1, 2, 2),第三次 (3, 3, 3), 第四次 (6, 4, 4)
return prev + cur;
}, 0)
console.log(arr, sum);// [1, 2, 3, 4],10
警惕:当reduce没有第二个参数initialValue的时候,且数组为空[],若函数有参数prev,则会报错,因为找不到第一项。
这样的话我们可以做数组的其他运算,求积,幂次方等等
高级用法
数组去重
var arr = [1, 2, 3, 3, 4, 2]
var newArr = arr.reduce((prev, cur) => {
if (!prev.includes(cur)) {
return prev.concat(cur)
} else {
return prev
}
}, [])
console.log(newArr)// [1, 2, 3, 4]
对象去重
var arr = [
{id: 0, name: "小明"},
{id: 1, name: "小张"},
{id: 2, name: "小李"},
{id: 3, name: "小孙"},
{id: 1, name: "小周"},
{id: 2, name: "小陈"}
]
var obj = {}
var newArr = arr.reduce((pre, cur) => {
obj[cur.id] ? '' : obj[cur.id] = true && pre.push(cur);
return pre
}, [])
console.log(newArr)
// 0: {id: 0, name: "小明"}
// 1: {id: 1, name: "小张"}
// 2: {id: 2, name: "小李"}
// 3: {id: 3, name: "小孙"}
es6如何去重
let arr = [1, 2, 3, 3, 4, 2]
let newArr = Array.from(new Set(arr))
console.log(newArr)// [1, 2, 3, 4]
计算数组中每个元素出现的次数
let arr = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let arrNum = arr.reduce((prev,cur)=>{
if(cur in prev){
prev[cur]++
}else{
prev[cur] = 1
}
return prev
},{})
console.log(arrNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
将二维数组转化为一维
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]
将多维数组转化为一维
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
对象属性求和
var result = [
{
subject: 'math',
score: 10
},
{
subject: 'chinese',
score: 20
},
{
subject: 'english',
score: 30
}
];
var sum = result.reduce(function(prev, cur) {
return cur.score + prev;
}, 0);
console.log(sum) //60