你应该知道的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

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》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具