这是我参与更文挑战的第6天,活动详情查看: 更文挑战
紧跟上一篇 ,这一篇主要了解高阶函数(Array.reduce())
什么是reduce?
-
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
-
reduce() 可以作为一个高阶函数,用于函数的 compose。
-
语法
array.reduce(function(prev, cur, index, arr), init)
-
prev (上一次调用回调返回的值,或者是提供的初始值(initialValue))
-
cur (数组中当前被处理的元素)
-
index (当前元素在数组中的索引)
-
arr (调用的数组)
-
init (传递给函数的初始值)
-
若传入初始值,accumulator首次迭代就是初始值,否则就是数组的第一个元素;后续迭代中将是上一次迭代函数返回的结果。所以,假如数组的长度为n,如果传入初始值,迭代次数为n;否则为n-1。
-
比如实现数组 arr = [1,2,3,4] 求数组的和
-
let arr = [1,2,3,4];
arr.reduce(function(pre,cur){return pre + cur}); // return 10
复制代码
- 浏览器支持情况
reduce的常见的几种的用法
- reduce累加
//带初始值
var arr = [1,2,3,4]
var sum = arr.reduce((pre, item) => {
return pre + item
}, 10)
console.log(sum) // 20
//不带初始值
var arr = [1,2,3,4]
var sum = arr.reduce((pre, item) => {
return pre + item
},)
console.log(sum) // 10
复制代码
- reduce数组去重
var arr = [1,2,3,3,2,1,4]
arr.reduce((acc, cur) => {
if (!(acc.includes(cur))) {
acc.push(cur)
}
return acc
}, [])
// [1, 2, 3, 4]
复制代码
- reduce求数组项最大值
var arr = [1, 2, 3, 4];
arr.reduce((prev, cur) => {
return Math.max(prev,cur);
});
//4
复制代码
- reduce将二维数组转为一维数组
var arr = [[1,2], [3,4], [5,6]]
arr.reduce((acc, cur) => {
return acc.concat(cur)
}, [])
// [1,2,3,4,5,6]
复制代码
- reduce对象里的属性求和
var arr = [
{subject: 'Math', score: 90},
{subject: 'Chinese', score: 90},
{subject: 'English', score: 100}
]
arr.reduce((pre, cur) => {
return cur.score + pre
}, 0)
//280
复制代码
- reduce计算数组中每个元素出现的个数
var arr = [1, 2,3,3,2,1,2,1]
arr.reduce((acc, cur) => {
if (!(cur in acc)) {
acc[cur] = 1
} else {
acc[cur] += 1
}
return acc
}, {})
//{1: 3, 2: 3, 3: 2}
复制代码
- reduce按属性给数组分类
var arr = [
{subject: 'Math', score: 90},
{subject: 'Chinese', score: 90},
{subject: 'English', score: 100},
{subject: 'Math', score: 80},
{subject: 'Chinese', score: 95}
];
arr.reduce((acc, cur) => {
if (!acc[cur.type]) {
acc[cur.type] = [];
}
acc[cur.type].push(cur)
return acc
}, {})
复制代码
- reduce实现map
var arr = [1, 2, 3, 4]
Array.prototype.reduceMap = function(callback) {
return this.reduce((acc, cur, index, array) => {
const item = callback(cur, index, array)
acc.push(item)
return acc
}, [])
}
arr.reduceMap((item, index) => {
return item + index
})
// [1, 3, 5, 7]
复制代码
- reduce实现forEach
var arr = [1, 2, 3, 4]
Array.prototype.reduceForEach = function(callback) {
this.reduce((acc, cur, index, array) => {
callback(cur, index, array)
}, [])
}
arr.reduceForEach((item, index, array) => {
console.log(item, index)
})
// 1234
// 0123
复制代码
- reduce实现filter
var arr = [1, 2, 3, 4]
Array.prototype.reduceFilter = function (callback) {
return this.reduce((acc, cur, index, array) => {
if (callback(cur, index, array)) {
acc.push(cur)
}
return acc
}, [])
}
arr.reduceFilter(item => item % 2 == 0) // 过滤出偶数项。
// [2, 4]
复制代码
- reduce实现find
var arr = [1, 2, 3, 4]
var obj = [{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }]
Array.prototype.reduceFind = function (callback) {
return this.reduce((acc, cur, index, array) => {
if (callback(cur, index, array)) {
if (acc instanceof Array && acc.length == 0) {
acc = cur
}
}
if ((index == array.length - 1) && acc instanceof Array && acc.length == 0) {
acc = undefined
}
return acc
}, [])
}
arr.reduceFind(item => item % 2 == 0) // 2
obj.reduceFind(item => item.a % 2 == 0) // {a: 2}
obj.reduceFind(item => item.a % 9 == 0) // undefined
复制代码
reduce的重要的用法
- 将数组转换为对象
- 在实际业务开发中,你可能遇到过这样的情况,后台接口返回的数组类型,你需要将它转化为一个根据id值作为key,将数组每项作为value的对象进行查找。
例如:
const peopleArr = [
{
id: 1,
username: 'limei',
sex: 0,
email: 'limei@163.com'
},
{
id: 2,
username: 'ajerry',
sex: 1,
email: 'jerrydfsd@qq.com'
},
{
id: 3,
username: 'jnancy',
sex: 0,
email: ''
}
];
function keyByUserReducer(acc, person) {
return {...acc, [person.id]: person};
}
const userObj = peopleArr.reduce(keyByUserReducer, {});
console.log(userObj);
复制代码
- 按顺序运行异步函数
- 我们可以做的另一件事.reduce()是按顺序运行promises(而不是并行)。如果您对API请求有速率限制,或者您需要将每个prmise的结果传递到下一个promise,reduce可以帮助到你
function fetchMessages(username) {
return fetch(`https://example.com/api/messages/${username}`)
.then(response => response.json());
}
function getUsername(person) {
return person.username;
}
async function chainedFetchMessages(p, username) {
// In this function, p is a promise. We wait for it to finish,
// then run fetchMessages().
const obj = await p;
const data = await fetchMessages(username);
return { ...obj, [username]: data};
}
const msgObj = userList
.map(getUsername)
.reduce(chainedFetchMessages, Promise.resolve({}))
.then(console.log);
// {glestrade: [ … ], mholmes: [ … ], iadler: [ … ]}
复制代码
-
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
-
请注意,在此我们传递Promise作为初始值Promise.resolve(),我们的第一个API调用将立即运行。
-
koa的源码中,有一个only模块,整个模块就一个简单的返回reduce方法操作的对象:
var only = function(obj, keys){
obj = obj || {};
if ('string' == typeof keys) keys = keys.split(/ +/);
return keys.reduce(function(ret, key){
if (null == obj[key]) return ret;
ret[key] = obj[key];
return ret;
}, {});
};
复制代码
- 通过对reduce概念的理解,这个模块主要是想新建并返回一个obj对象中存在的keys的object对象。
var a = {
env : 'development',
proxy : false,
subdomainOffset : 2
}
only(a,['env','proxy']) // {env:'development',proxy : false}
复制代码
- 以上所述是给大家介绍的详解JS数组Reduce()方法详解及高级技巧,希望对大家有所帮助
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END