JS Array.reduce 实现 Array.map 和 Array.filter

栏目: 编程语言 · 发布时间: 5年前

内容简介:继上一篇实现了自己的

继上一篇 Array.prototype.reduce 后,我立志要好好学习。琢磨了很久,再加上最近看了几篇"JS 函数式编程"的文章和书籍后,然后有感而发写下了这篇文章。

Array.prototype.map 方法相信大家都用的很熟悉了,同时我也相信很多人已经自己实现了 map 函数。没有实现过自己的 map ? 没关系,我们先用 for 循环来实现下。

Array.prototype.selfMap = function () {
      const ary = this
      const result = []
      const [ fn, thisArg ] = [].slice.call(arguments)
      if (typeof fn !== 'function') {
        throw new TypeError(fn + 'is not a function')  
      }
      for (let i = 0; i < ary.length; i++) {
        result.push(fn.call(thisArg, ary[i], i, ary))
      }
      return result
  }
  
  const a = new Array(1, 2, 3, 4)
  a.selfMap(item => item + 1) // [ 2, 3, 4, 5 ]
复制代码

实现了自己的 map ,还不是美滋滋。

但是,这和本文没有半点关系,因为我是要用 reduce 实现 map

众所周知, map 函数需要传一个函数的,还有一个可选的 this 参数,但是我发现第二个参数大家很少用到,也不怎么注意,我也是这样。

[1, 2, 3].map(function(item) {
    console.log(this)
    return item
}, { msg: 'mapping' })
复制代码

上面:point_up_2:这段代码块不仅会返回一个新的数组,还会在控制台打印三次

{ msg: 'mapping' }
复制代码

有图有真相:point_down:

JS Array.reduce 实现 Array.map 和 Array.filter

可能有的小伙伴在验证我上面的例子时,会使用 箭头函数 ,然后发现总是打印 window ,就是下面这样:point_down:

JS Array.reduce 实现 Array.map 和 Array.filter

然后心里暗道“无耻小儿,竟敢骗我”。心里苦啊,箭头函数在声明时就绑定了它外层的this(此例的 thiswindow ,而且还改变不了, 也就是说 { msg: 'mapping' } 相当于白传了):sob:

似乎废话有点多额,那我们先用 reduce 来实现 map 吧(默认运行环境支持 Array.prototype.reduce ,如果不支持的话,那还写个:hammer:)

// 这次不把方法写在Array的原型上
    const reduceMap = (fn, thisArg /*真想去掉thisArg这个参数*/ ) => {
        return (list) => {
            // 不怎么愿意写下面这两个判断条件
            if (typeof fn !== 'function') {
                throw new TypeError(fn + 'is not a function')  
            }
            if (!Array.isArray(list)) {
                throw new TypeError('list must be a Array')
            }
            if (list.length === 0) return []
            return list.reduce((acc, value, index) => {
                acc.push(fn.call(thisArg, value, index, list))
                return acc
            }, [])
        }
    }
    
    // 来使用下怎么样  
    
    reduceMap(x => x + 1)([ 1, 2, 3 ]) // [ 2, 3, 4 ]
    
    const mapAry1 = reduceMap(function(item) {
        console.log(this)
        return item + 1
    }, { msg: 'mapping' })([ 1, 2, 3 ]) 
    // [ 2, 3, 4 ] 
    // logging { msg: 'mapping' } three times
复制代码

:point_up_2:实现的原理相信大家应该都懂吧。

打铁当趁热,继续来实现 filter 吧。

  • for 循环实现版
Array.prototype.selfFilter = function () {
    const ary = this
    const result = []
    const [ fn , thisArg ] = [].slice.call(arguments)
    
    if (typeof fn !== 'function') {
        throw new TypeError(fn + 'is not a function')  
    }
    
    for (let i = 0; i < ary.length; i++) {
        if (fn.call(thisArg, ary[i], i, ary)) {
            result.push(ary[i])
        }
    }
    return result
}

const a = new Array(1, 2, 3)
a.selfFilter(item => item % 2 === 0) // [ 2 ]
a.selfFilter(function (item) {
    console.log(this)
    return item % 2 === 0
})
// [ 2 ]
// logging {} three times
复制代码
  • reduce 实现版
// 同map, 不定义在Array的原型上
const reduceFilter = (fn, thisAry /* thisAry知不知你好讨厌啊 */ )  => {
    return (list) => {
        if (typeof fn !== 'function') {
            throw new TypeError(fn + 'is not a function')  
        }
        if (!Array.isArray(list)) {
            throw new TypeError('list must be a Array')
        }
        if (list.length === 0) return []
        return list.reduce((acc, value, index) => {
            fn.call(thisAry, value, index, list) ? acc.push(value) : null
            return acc
        }, [])
    }    
}

reduceFilter(x => x % 2 === 0)([ 1, 2, 3 ]) // [ 2 ]

复制代码

文章里掺杂了些许 函数式编程 里面的东西,因为我也才开始学函数式编程不久,就不在大佬们面前献丑了。如果文章里有哪里写的不对或者不够准确,亦或者是觉得有写的不好的地方,烦请各位指正,也让我改正。


以上所述就是小编给大家介绍的《JS Array.reduce 实现 Array.map 和 Array.filter》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

GitHub入门与实践

GitHub入门与实践

[日] 大塚弘记 / 支鹏浩、刘斌 / 人民邮电出版社 / 2015-7 / 39.00元

本书从Git的基本知识和操作方法入手,详细介绍了GitHub的各种功能,GitHub与其他工具或服务的协作,使用GitHub的开发流程以及如何将GitHub引入到企业中。在讲解GitHub的代表功能Pull Request时,本书专门搭建了供各位读者实践的仓库,邀请各位读者进行Pull Request并共同维护。一起来看看 《GitHub入门与实践》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码