你应该知道的JS: reduce的n种应用

栏目: JavaScript · 发布时间: 5年前

内容简介:假如你还不知道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 ,相当于依次执行了 toUpperCaseadd :

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 还有更多种神奇的应用,等待着各位小伙伴的发现和使用。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High-Performance Compilers for Parallel Computing

High-Performance Compilers for Parallel Computing

Michael Wolfe / Addison-Wesley / 1995-6-16 / USD 117.40

By the author of the classic 1989 monograph, Optimizing Supercompilers for Supercomputers, this book covers the knowledge and skills necessary to build a competitive, advanced compiler for parallel or......一起来看看 《High-Performance Compilers for Parallel Computing》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具