在前端开发过程、或者面试过程中,别人问你数组常用的操作,你也许立刻马上回答for
循环、forEach
、for..of
、 map
、some
……reduce
等方法。我相信前端开发的小伙伴,10个人中有8个对reduce
仅仅是停留在数据累加上, 下面本人介绍一些reduce
函数的妙用之处。
一、回顾下reduce
函数的参数问题
- 1、
reduce
函数
Array.prototype.reduce(function(previousVal, currentVal, index, _this) {
// 函数体
}, initVal);
- 2、理解上面的函数
- 1.
reduce
函数也是对数组迭代的过程 - 2.第一次循环的时候,
previousVal==initVal
的 - 3.从第二次开始,
previousVal==reducer
函数中的返回值了 - 4、
index
表示当前数组的序列化 - 5、
_this
表示当前的数组
- 1.
二、自己手动实现一个reduce
函数
- 1、自己扩展数组的方法
Array.prototype.myReduce = function(fn, initVal) {
if (Object.prototype.toString.call(this) != '[object Array]') {
throw new Error('当前是数组的方法,不能使用到别的上面');
}
let total;
if (initVal != undefined) {
total = initVal;
} else {
total = this[0];
}
if (initVal === undefined) {
for (let i = 1; i < this.length; i++) {
total = fn(total, this[i], i, this);
}
} else {
for (let [index, val] of this.entries()) {
total = fn(total, val, index, this);
}
}
return total;
};
一、数据累加
- 1、数据原
let ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- 2、数据叠加
const result = ary1.reduce((pre, cur) => pre + cur);
console.log(result);
二、将数组转换为对象
- 1、实现代码
const userList = [
{
id: 1,
username: 'john',
sex: 1,
email: 'john@163.com'
},
{
id: 2,
username: 'jerry',
sex: 1,
email: 'jerry@163.com'
},
{
id: 3,
username: 'nancy',
sex: 0,
email: ''
}
];
let result = userList.reduce((pre, current) => {
return {...pre, [current.id]: current};
}, {});
console.log(result);
三、将大数组转换成小数组
- 1、实现代码
const fileLines = [
'Inspector Algar,Inspector Bardle,Mr. Barker,Inspector Barton',
'Inspector Baynes,Inspector Bradstreet,Inspector Sam Brown',
'Monsieur Dubugue,Birdy Edwards,Inspector Forbes,Inspector Forrester',
'Inspector Gregory,Inspector Tobias Gregson,Inspector Hill',
'Inspector Stanley Hopkins,Inspector Athelney Jones'
];
let result = fileLines.reduce((pre, current) => {
return pre.concat(current.split(/,/g));
}, []);
console.log(result);
四、将数组展开
- 1、实现代码
const arr = ["今天天气不错", "", "早上好"];
const arr2 = arr.reduce((pre, cur) => {
return pre.concat(cur.split(''));
}, []);
console.log(arr2);
五、求数组的最大值与最小值
- 1、实现代码
const readings = [0.3, 1.2, 3.4, 0.2, 3.2, 5.5, 0.4];
let minValue = readings.reduce((x,y) => Math.min(x,y));
console.log(minValue);
let maxValue = readings.reduce((x,y) => Math.max(x,y));
console.log(maxValue);
六、使用reduce
写一个工具方法,用来提取对象中的数据
- 1、后端返回的一个对象
let obj1 = {
"result": {
"report": {
"contactInfo": {
"callsNumber": 0,
"contactsNumber": 0,
"emergencyContactHasOverdue": "No",
"sameLiainson": {
"isSame": "Yes",
"accounts": "aa"
}
}
}
}
};
- 2、使用
reduce
的工具方法
const objectGetVal = (obj, expr) => {
if (!Object.is(Object.prototype.toString.call(obj), '[object Object]')) {
throw new Error(`${obj}不是对象`);
}
if (!Object.is(Object.prototype.toString.call(expr), '[object String]')) {
throw new Error(`${expr}必须是字符串`);
}
return expr.split('.').reduce((prev, next) => {
if (prev) {
return prev[next]
} else {
return undefined;
}
}, obj)
};
console.log(objectGetVal(obj1, 'result.report.contactInfo.emergencyContactHasOverdue'));
console.log(objectGetVal(obj1, 'result.report.emergencyContactHasOverdue'));
// 输出结果
// No
// undefined