你应该知道的JS: reduce的n种应用
栏目: JavaScript · 发布时间: 7年前
内容简介:假如你还不知道reduce的用法,请先阅读下MDN文档中关于reduce的介绍。(不得不说,MDN文档太强大了,里面列举了很多有用的方法)本文将介绍借助reduce函数,利用其
reduce
是ES5中新引入的一个API。
假如你还不知道reduce的用法,请先阅读下MDN文档中关于reduce的介绍。(不得不说,MDN文档太强大了,里面列举了很多有用的方法)
本文将介绍借助reduce函数,利用其 能够遍历到数组的每一个元素,并且次遍历都可以使用上次遍历结果 的特性,实现的一些功能。
1.累和/累积
let arr = [1, 2, 3, 4, 5] console.log(arr.reduce((prev, cur) => prev + cur)) // 15 // 可以实现另类的阶乘 console.log(arr.reduce((prev, cur) => prev * cur)) // 120 复制代码
2.求最大值/最小值
let arr = [1, 2, 3, 4, 5] console.log(arr.reduce((prev, cur) => Math.max(prev, cur))); // 5 console.log(arr.reduce((prev, cur) => Math.min(prev, cur))); // 1 复制代码
3. 数组去重
当 reduce
接收两个参数时,即 reduce(fn, init)
, init
将作为 fn
的第一个参数 prev
传入。
这里,将一个空数组 []
作为去重后的新数组,通过做判断,如果该容器内已经存在某元素,就啥也不做;反之,如果该容器内还没有一个元素,就将其推入容器。
let arr = [1, 2, 3, 1, 1, 2, 3, 3, 4, 3, 4, 5]
let res = arr.reduce((prev, cur)=>{
!prev.includes(cur) && prev.push(cur)
return prev
}, [])
console.log(res) // [ 1, 2, 3, 4, 5 ]
复制代码
4.实现map函数
map
函数接收一个函数作为参数,作为参数的函数接收三个参数值,分别是遍历数组的每一项元素,元素的索引和数组本身。这三个参数刚好和 reduce
函数接收的第一个函数参数的第2、3、4个参数是对应的。
实现思路是, 将每次遍历的元素,作为传入的函数的参数,并将函数执行的结果放入新的数组中 。
let arr = [1, 2, 3]
Array.prototype._map = function(cb) {
if(typeof cb === 'function') {
// this: 调用_map方法的当前数组对象
let arr = this;
return arr.reduce((prev, item, index, array) => {
prev.push(cb(item, index, array))
return prev
}, [])
} else {
throw new Error(cb + ' is not function')
}
}
let res = arr._map(n => n*2)
console.log(res) // [ 2, 4, 6 ]
复制代码
5.实现filter函数
实现 filter
的思路和实现 map
是一致的,只不过后者是一股脑的把执行结果全放入数组中,而 filter
需要做一个判断:
如果 filter
函数传入的参数(参数是一个函数)执行后有返回值,即经过了检验,才将遍历的当前元素放入数组中,如果没有返回值,就忽略
。
let arr = [1, 2, 3, 4, 5];
Array.prototype._filter = function(cb) {
if(typeof cb === 'function') {
let arr = this;
return arr.reduce((prev, item, index, array) => {
cb(item, index, array) ? prev.push(item) : null
return prev
}, [])
} else {
throw new Error(cb + ' is not function')
}
}
let res = arr._filter(n => n>2)
console.log(res) // [ 3, 4, 5 ]
复制代码
6.实现compose
compose
是函数式编程的核心思想,简单说就是 将若干个函数组合成一个函数来执行,并且每个函数执行的结果都能作为下一个函数的参数
。这也是使用 reduce
实现 compose
的思路。
假设有两个函数,作用分别是将字符串转为大写,在字符串末尾追加感叹号:
function toUpperCase(str) {
return str.toUpperCase();
}
function add(str) {
return str += '!'
}
复制代码
一般情况下,会这样使用:
var str = 'hello world' var res = toUpperCase(str) res = add(res) console.log(res); // HELLO WORLD! 复制代码
使用 compose
后,效果是这样的,执行 fn
,相当于依次执行了 toUpperCase
和 add
:
var fn = compose(add, toUpperCase) console.log(fn(str));// HELLO WORLD! 复制代码
接下来实现一下 compose
:
function compose() {
let args = [].slice.call(arguments)
return function (x) {
// 因为compose()接收的函数参数,是从右往走顺次执行的,
// 所以这里使用reduceRight, 用法和reduce一致,只不过是从右往左遍历数组。
return args.reduceRight((prev, cur) => {
return cur(prev)
}, x)
}
}
复制代码
7.数组扁平化
数组扁平化,针对的是多维数组,将其扁平、展开,成为一维数组。
let arr = [1, 2, '3js', [4, 5, [6], [7, 8, [9, 10, 11], null, 'abc'], {age: 12}, [13, 14]], '[]'];
function flatten(arr) {
if(Array.isArray(arr)) {
return arr.reduce((prev, cur) => {
// 如果遍历的当前项是数组,再迭代展平
return Array.isArray(cur) ? prev.concat(flatten(cur)) : prev.concat(cur)
}, [])
} else {
throw new Error(arr + ' is not array')
}
}
console.log(flatten(arr));
复制代码
结束
当然,除了以上几种, reduce
还有更多种神奇的应用,等待着各位小伙伴的发现和使用。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Open Data Structures
Pat Morin / AU Press / 2013-6 / USD 29.66
Offered as an introduction to the field of data structures and algorithms, Open Data Structures covers the implementation and analysis of data structures for sequences (lists), queues, priority queues......一起来看看 《Open Data Structures》 这本书的介绍吧!