• javaScript之数组中reduce的详细介绍及使用


    一、reduce功能介绍及定义(自我理解)

    1. reduce方法为数组中的一个高阶函数,接受两个参数,第一个参数为回调函数,第二个为初始值。如果不给入初始值则会以数组第一项为初始值!
    2. reduce会循环数组每一项,并且会保留上一次循环的结果供下一次循环使用,最终结果为数组循环完毕后的最终返回(return)的值。
    3. 那这样咱们就可以这么理解了,给入一个初始值,后续操作都在给这个初始值做修饰!比如说给入对象最终返回对象、给入数组最终返回数组、给入字符串最终返回字符串、给入Boolean值最终返回Boolean值(true | false)…
    4. 再然后我们捋捋装饰器模式:允许向现有的对象添加功能,且不能影响它的构成(比如说一个人,你可以给他添加英语能力、可以给他添加法语能力,但是你不能让这个人的手没了),这么一看reduce不就是非常适合循环给对象添加功能吗?这不就是满足了装饰器模式了嘛。

    二、各种使用方式

    1. 全网都有的最简单例子:累加递增
    const arr = [1, 2, 3, 4, 5, 99]
    arr.reduce((pre, next) => pre + next) // 114
    
    • 1
    • 2
    1. 【模仿数组includes】简单的includes功能模仿实现(返回某值是否在数组中出现过)
            const fn = () => { console.log(11) }
            const obj = {}
            const arr = [2, '2', fn, obj]
            const selfIncludes = (arr, value) => {
                // 使用try catche的原因是快速跳出循环。
                try {
                    return arr.reduce((pre, next) => {
                        if (next === value) throw true
                        return false
                    }, false)
                } catch (end) {
                    if (typeof end === 'boolean') return true;
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 【模仿数组indexOf】简单的indexOf功能模仿实现(返回最先找到值的索引,没找到则返回-1)
            const fn = () => { console.log(11) }
            const obj = {}
            const arr = [2, '2', fn, obj]
            const selfIndexOf = (arr, value) => {
                // 使用try catche的原因是快速跳出循环。
                try {
                    return arr.reduce((pre, next) => {
                        if (next === value) throw pre
                        return ++pre
                    }, 0) && -1
                } catch (end) {
                    if (typeof end === 'number') return end;
                }
            }
            console.log(selfIndexOf(arr, fn))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 【模仿数组map】简单的map功能模仿实现(循环遍历数组最终返回处理后的值)
            const fn = () => { console.log(11) }
            const obj = {}
            const arr = [2, '2', fn, obj]
            const selfMap = (arr, fn) => {
                return arr.reduce((pre, next) => {
                    // map方法并没有这一步
                    // pre.push(fn?.(next, pre.length) || next)
                    pre.push(fn(next, pre.length))
                    return pre 
                }, [])
            }
            console.log(selfMap(arr, (item, i) => {
                return {
                    name: item,
                    index: i
                }
            }))
            console.log(selfMap(arr, () => {}))
            console.log(arr.map(() => {}))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    1. 【模仿数组flat】简单的flat方法模拟实现(给数组内部子集合进行将为)(递归)
    	const selfFlat = (arr, deep) => {
    	  if (deep > 0)
    	    return arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? flat(cur, deep - 1) : cur), [])
    	  return arr.slice()
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    调用:selfFlat([1, [2], [[3], [4]], [[[5], [6]]]], 2)
    结果:(6) [1, 2, 3, 4, Array(1), Array(1)]
    
    调用:selfFlat([1, [2], [[3], [4]], [[[5], [6]]]], 3)
    结果:(6) [1, 2, 3, 4, 5, 6]
    
    调用:selfFlat([1, [2], [[3], [4]], [[[5], [6]]]], Infinity)
    结果:(6) [1, 2, 3, 4, 5, 6]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 过滤掉对象中为undefined、null、空字符串、NaN的key与值
        const filterParam = (obj) => Object.entries(obj).reduce((pre, [key, value]) => {
          // 这里添加你需要做的判断依据
          if (value || value === 0) pre[key] = value
          return pre
        }, {});
        console.log(filterParam({name: undefined, age: 0, class: 'ant-design', test: NaN}))
        // {age: 0, class: 'ant-design'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. lodash 中 keyBy 功能简单实现(具体细节不考虑)(使用数组内部每项的某个key对应的值为最终生成对象的key,数组当前项为最终生成对象的值)
    	const arr =  [
    		{
    			name: '张三',
    			age: 16
    		},
    		{
    			name: '李四',
    			age: 17
    		},
    		{
    			name: '王五',
    			age: 18
    		},
    	]
    	const keyBy = (array, key) => {
    		return array.reduce((pre, next) => {
    			pre[next[key]] = next;
    			return pre;
    		}, {})
    	}
    	console.log(
    		keyBy(arr, 'name')
    	)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    1. 装饰器模式演示(创建Person这个类,添加一个zs的Person,把skillArr中的技能教给zs,最后让zs使用学习到的技能)
            class Person {
                // 技能对象
                skill = {
                    中文: (string) => {
                        // ..... 此处经过一系列的翻译(比如说调用百度的翻译)
                        return string;
                    }
                }
                constructor(params) {
                    // 初始化信息
                    this.info = params;
                }
                // 学习技能的功能函数
                studySkill(skillName, skillFn) {
                    if (this.skill[skillName]) return '这个技能我会!';
                    this.skill[skillName] = skillFn;
                    return `${skillName}学习完成`;
                }
                // 说话的功能函数
                say(string, way) {
                    if (!this.info.isLanguage?.includes(way)) return '你确定这是一门语言吗?';
                    if (!this.skill[way]) return '我不会这个语言!';
                    return this.skill[way](string);
                }
            };
            const zs = new Person({
                name: 'zs',
                age: 18,
                isLanguage: ['中文', '英语', '法语', '俄语']
            });
            // 可学习的语言技能数组
            const skillArr = {
                英语: (string) => {
                    // ..... 此处经过一系列的翻译(比如说调用百度的翻译)
                    const end = 'Hello world';
                    return end;
                },
                法语: (string) => {
                    // ..... 此处经过一系列的翻译(比如说调用百度的翻译)
                    const end = 'Bonjour, le monde.';
                    return end;
                },
                中文: (string) => {
                    // ..... 此处经过一系列的翻译(比如说调用百度的翻译)
                    const end = '你好,世界。';
                    return end;
                }
            }
            // reduce 主题
            Object.entries(skillArr).reduce((pre, next) => {
                const [skillName, skillFn] = next;
                const sayMessage = pre.studySkill(skillName, skillFn);
                console.log(sayMessage);
                return pre;
            }, zs);
            // --------------
            console.log(zs);
            console.log(zs.say('你好', '英语')) // Hello world
            console.log(zs.say('你好', '法语')) // Bonjour, le monde.
            console.log(zs.say('你好', '中文')) // 你好
            console.log(zs.say('你好', '俄语')) // 我不会这个语言!
            console.log(zs.say('你好', '鸟语')) // 你确定这是一门语言吗?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    在这里插入图片描述

    总结

    1. reduce是真的强大,数组内部的方法应该都可以用 reduce 去实现,有兴趣的小伙伴可以去试试看。
    2. reduce是从左往右循环执行,还有一个 reduceRight 是从右往左循环执行!
    3. reduce的返回值取决于设置的初始值(常规用法),但是这也不是绝对的(非常规用法)!
  • 相关阅读:
    JDK、JRE和JVM
    Django生鲜蔬菜采购系统-计算机毕设 附源码 24033
    阿里P8架构师谈微服务架构:Dubbo+Docker+SpringBoot+Cloud
    内置类型、引用类型的比较
    ELK日志监控平台(三)---kibana数据可视化
    node版本管理工具nvm的安装卸载与使用(windows)
    Python面向对象初始化函数是什么?初始化方法
    JavaEE基础知识
    【Computer Composition】Part1 计算机系统概述小结
    Python 数据容器(2) - tuple(元祖)
  • 原文地址:https://blog.csdn.net/weixin_47436633/article/details/127870209