js reduce

323 阅读3分钟

js reduce:

1、定义和用法

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。reduce() 可以作为一个高阶函数,用于函数的 compose。

注意: reduce() 对于空数组是不会执行回调函数的。

2、语法

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
1、total (必需。初始值, 或者计算结束后的返回值)。
2、currentValue (必需。当前元素)
3、currentIndex (可选。当前元素的索引)
4、arr (可选。当前元素所属的数组对象。)
5、initialValue (可选。传递给函数的初始值)

3、initialValue 参数(实例解析)

example 1:

var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(total, currentValue, currentIndex, arr) {
    console.log('test1----',
    		'total:',total, 
    		'currentValue:',currentValue,  
                'currentIndex:',currentIndex);
    return total + currentValue;
})
console.log('test2----','arr:',arr,'sum:', sum);

打印结果:

test1---- total: 1 currentValue: 2 currentIndex: 1
test1---- total: 3 currentValue: 3 currentIndex: 2
test1---- total: 6 currentValue: 4 currentIndex: 3
test2---- arr: (4) [1, 2, 3, 4] sum: 10

可以看出,上面的例子index是从1开始的,第一次的total的值是数组的第一个值。数组长度是4,但是reduce函数循环3次。

example 2:

var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(total, currentValue, currentIndex, arr) {
    console.log('test1----',  
    	        'total:',total, 
   	 	'currentValue:',currentValue,   
                'currentIndex:',currentIndex);
    return total + currentValue;
},0)
console.log('test2----','arr:',arr,'sum:', sum);

打印结果:

test1---- total: 0 currentValue: 1 currentIndex: 0
test1---- total: 1 currentValue: 2 currentIndex: 1
test1---- total: 3 currentValue: 3 currentIndex: 2
test1---- total: 6 currentValue: 4 currentIndex: 3
test2---- arr: (4) [1, 2, 3, 4] sum: 10

可以看出,上面的例子index是从0开始的,第一次的total的值是我们设置的初始值0,数组长度是4,reduce函数循环4次。

结论:

如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。

4、数组为空的情况

var arr = [];
var sum = arr.reduce(function(total, currentValue, currentIndex, arr) {
    console.log('test1----',
    	'total:',total, 
    	'currentValue:',currentValue,   
        'currentIndex:',currentIndex);
    return total + currentValue;
})
console.log('test2----','arr:',arr,'sum:', sum);

打印结果: Uncaught TypeError: Reduce of empty array with no initial value

设置初始值:

var arr = [];
var sum = arr.reduce(function(total, currentValue, currentIndex, arr) {
    console.log('test1----',
    	'total:',total, 
    	'currentValue:',currentValue,   
        'currentIndex:',currentIndex);
    return total + currentValue;
},0)
console.log('test2----','arr:',arr,'sum:', sum);

打印结果:

test2---- arr: [] sum: 0

在项目中使用reduce方法,如果数组有为空的情况,最好设置初始值,防止代码报错

5、reduce简单用法:作为累加器函数,进行求和、求乘

var  arr = [1, 2, 3, 4];
var sum = arr.reduce((x,y)=>x+y)
var mul = arr.reduce((x,y)=>x*y)
console.log( sum ); //求和,10
console.log( mul ); //求乘积,24

6、reduce高级用法:

(1)计算数组中每个元素出现的次数

let  language = ['Chinese', 'English', 'Japanese', 'Chinese', 'English'];
let  languageNum = language.reduce((total,cur)=>{
    if(cur in total){
        total[cur]++
    }else{
        total[cur] = 1
    }
    return total
},{})
console.log(languageNum); //{Chinese: 2, English: 2, Japanese: 1}

(2)数组去重

let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((total,cur)=>{
    if(!total.includes(cur)){
        return total.concat(cur)
    }else{
        return total
    }
},[])
console.log(newArr);// [1, 2, 3, 4]

(3)求数组最大值(最小值同理)

let arr = [23,123,342,12];
let max = arr.reduce((total,cur,index,arr) => {
    return total > cur ? total : cur
});
console.log(max) //342

(4)将字符串转换为整数

let arr = [68,168,666,12];
let max = arr.reduce((total,cur,index,arr) => {
    return total > cur ? total : cur
});
console.log(max) //666

(5)将字符串转换为整数

let str = '1688';
let strParseInt = str.split('')                   // 得到 ['1', '6', '8', '8']
    .map(item => {return item.charCodeAt() - 48}) // 得到 [1, 6, 8, 8]
    .reduce((a, b) => {return a * 10 + b})        // 得到 1688
console.log(strParseInt)

(6)二维数组转化为一维

let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((total,cur)=>{
    return total.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]

(7)多维数组转化为一维

let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
    return arr.reduce((total,cur)=>total.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]

(8)对象里的属性求和

var result = [{
    subject: 'male',
    score: 45
}, {
    subject: 'female',
    score: 50
}];

var sum = result.reduce(function(total, cur) {
return cur.score + total;
}, 0);
console.log(sum) //95

参考链接:

www.jianshu.com/p/e375ba1cf…
segmentfault.com/a/119000001…

在项目中的运用

import resources from '@/utils/locales/resources.js'
import i18n from "i18next";
//获取不确定路径深度的值
const getObj = (obj,path,defaultVal) => {
    let pathCopy = path.split('.')
    return pathCopy.reduce((pre,cur)=>{
        return (pre||{})[cur]
    },obj) || defaultVal
}
let t = (type)=>{
    let obj = resources[i18n.language]['translation']
    return getObj(obj,type,'')
}
export default t