少侠,你的transducer到了,请拿去装逼~

[图片上传失败...(image-dc4ef6-1581321611007)]

少侠们好~

上次和大家分享了一个关于降低遍历数组时所耗能量的技巧。

通过这个技巧,我们把一开始的代码:

image

变成了下面这样:

image

而且在最后,我说了这次会给大家分享一个新的武器,也就是下面这个东西:

image

这个东西可不好弄,费了挺大劲,不过还好,最后总算给弄来了,

那么,

有的少侠可能要问了:

“天辰,既然这样,你费这么劲弄来的这个武器到底有啥用?”

少侠!

既然你诚心诚意的发问了,

我就大发慈悲的告诉你!

为了防止世界被破坏,

为了维护世界的和平,

贯彻爱与真实的邪恶,

潇洒又迷人的反派角色

天辰……dreamer……

“喂,天辰,你是不是走错片场了?!!!”

“。。。。。。。。”

重新回到刚才的问题来,

这里正确答案应该可能是:

1、上面最后的代码虽然降低了遍历次数,但是,逻辑比较耦合,不利于扩展,transduce就是为了解决这个问题,在保持性能的前提下,也有比较好的扩展性。

2、transducer依赖了很多关键知识点,学习transducer能够帮助少侠你更好的理解它们。

3、学习transducer能够很好的锻炼抽象思维,帮助少侠们打开脑洞。

、能够用来装逼~

好了,

现在开始进入正题~

为了理解transduce, 我们首先需要理解reduce,

我们先来回顾一下上次最后时刻的代码:

image

在最后,我们只用一个reduce函数,就实现了过滤,映射,以及最后的叠加操作。

少侠你应该也发现了,

reduce函数比我们想象中的更厉害,

那么,

既然reduce函数这么强大,我们能不能用它来代替map或者filter函数呢?

对于这个问题,

有的少侠可能会说了,

“切~,既然天辰你都这么问了,那答案肯定是能啊,要不然你问它干嘛?”

对于这类少侠,天辰想说的是:

“就TM你话多!~”

但是~

我们确实可以用reduce实现map和filter一样的效果。

还是从简单的例子开始:

这有一个数组:

image

用map翻倍nums中的数字:

image

用filter过滤掉nums中的奇数:

image

是不是觉得很简单?

那么我们如何使用reduce实现相同的效果呢?

也很简单!

少侠请看~

使用reduce翻倍nums里面数字:

image

使用reduce过滤nums中的奇数:

image

怎么样!很简单吧?

翻倍数字了吧?

过滤出奇数了吧?

到这里,少侠你心里肯定在想:

image

哈哈,少侠你先别激动!

虽然上面两个例子是有点过分~

但是!

(这里请自动切换成严肃脸~😐)

通过上面2个例子,我们至少明白了一件事,

那就是reduce是能够给我们想要的结果的,

它既可以像map那样,对一些元素执行操作,然后给我们一个相同长度的数组;

也可以像filter一样,给我们一个过滤掉某些元素后的比较短的数组;

或者其他一些奇奇怪怪的东西~

那么,

接下来我们的问题就是,

如何让reduce返回给我们想要的东西呢?

这里少侠你可能有2种情况,

第一种就是,你已经知道了你想要的结果,然后你直接通过reduce最后返回这个结果,也就是上面两个例子。。。

换句话说,reduce实际上啥也没做,只不过进去兜了一圈。。。

“reduce老弟,天辰那家伙又来翻倍nums数组了,上次是什么结果你还记得不?”

“记得,是 [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]”

“好,直接扔给它,我们出去玩去~”

“嗯,好~”

image

当然,如果少侠你没有我天辰这么优秀~

你很可能没办法在一开始就知道具体的结果是什么,

这个时候,你就得自己告诉reduce如何生成你想要的元素了,

比如这样:

image

换个简单些的写法,同时把reduce里面的函数放到外面来:

image

好了,少侠~

我们已经初步实现了map的效果,那么接下来就应该是filter了,

一样的思路:

image

现在filter也有了,

我们把两种reducer结合起来使用一遍:

image

完全OK~

到这里,有的少侠可能就要说了:

“住手!天辰,你这样的话,你不是又要遍历2次数组,上次装逼时怎么说的你自己都忘了?!”

好吧,少侠,你还算是一个比较细心的人,

这里我们用了两次reduce, 所以确实会遍历2次数组,

但是~

谁说我就一定得用2次reduce了?

看好了,

少侠~

接下来我要开始装逼了,

基础内力不深厚的少侠请主动退后10米站远一些!

首先,

我们已经把mapReducer里面的翻倍操作提取出来了,

也就是我们熟悉的double函数,

现在,我们试着把mapReducer里面的向数组添加值的这个操作,

也单独提取出来:

image

然后,按照我们上一章说的,

mapReducer现在会严重依赖当前作用域中的double函数和pushValue函数,

所以,我们给它换种方式,换成通过传参的形式获取:

image

注意,少侠~

这里看着可能稍微复杂了一些,

但是所有我们做的,

实际上就只是把原先直接通过作用域访问的函数,

换成了依次通过函数参数传递访问而已,

把函数改成通过参数传递之后,

我们每次就可以自由选择传递什么函数进去,

比如,把double函数换成add1:

image

根据这个思路,

改变后的filterReducer会是这样:

image

到这里,如果少侠你有点懵逼的话。。。

别急,

待会儿你可能会更懵逼的!

以后有机会我们会回头单独分析里面的知识点的。。。

这里的重点是,现在我们可以更灵活的使用reduce了:

image

我知道你们想说什么~

现在还是用了2次reduce。。。

少侠你看,我现在在最后传递的是pushValue作为joinFn函数,

也就是说,过滤出奇数后,就添加到数组当中,

但是,我也可以,在添加到数组当中之前,不马上添加到数组中,

我们先翻倍一下过滤出的奇数,

完了过后再添加到数组当中~

image

现在只有一次reduce了!

然后,

不知道少侠你有没有注意到,

magic函数实际上可以用mapReducer函数实现

(请仔细认真观察~)

image

替换掉magic:

image

好了,

装逼结束~

哈哈哈哈哈哈!

“喂,天辰!你在这儿吹什么牛逼呢,你是不是忘了什么东西?说好的transduce呢!!!”

哦,差点忘了。。。

好吧,少侠,

transduce就是对下面这部分代码的进一步抽象:

image

但是,

老实说,

解释transduce比我想象的还要麻烦。。。

(早知道就该不选这个东西。。。。)

首先,

transduce通常需要一个compose函数配合使用:

image

有了compose函数,我们就可以简化下面的代码:

image

然后,

transduce大概长这个样子:

image

里面的参数分别对应下面几个部分:

image

其实就是把开始的几个部分拆分了开来,

这是它的使用方式,

image

把所有代码结合起来:

image

如果我们想增加一条过滤条件:

image

或者如果我们最后不是想获得数组,

而是给数组里面的数字求和的话:

image

好了,

恭喜你,少侠!

你又成功发现并阅读完了一篇文章~

按照惯例,首先~

谢谢少侠你看到了这里,

然后~

有的少侠可能会对这篇文章觉得比较懵逼,

这很正常,

一是少侠我可能写得也不是很清楚,

还有就是transduce的实现确实涉及到了很多其他的知识,

一大堆高阶函数,函数闭包,偏函数应用,以及函数组合compose等,

那么我为什么要把transduce分享给大家呢?

因为,

transduce本身也许并不是很重要,

少侠你完全可以不使用它,

但是,理解和掌握它所需的知识,对很多少侠来说都很重要,

特别是对想追求卓越,当一个dreamer的少侠~

还有就是。。。

如果少侠你平时对高阶函数,闭包,this关键字这些东西都比较懵逼的话,

比较抗拒的话~

那么,先看看更懵逼的东西,

等回过头再来看它们,

你会觉得它们亲切多了~

所以~

少侠,

你到底懵逼了没?


一些你可能关心的问题:

1、天辰,你老实说!你写这篇文章是不是就是想装逼?

少侠,装逼能帮我吸引到妹子不?

如果能,那我就是在装逼,

如果不能,那我就是在分享技术文章。。。

2、天辰,这次你弄了个感觉没什么用的transduce,下次又打算弄什么东西来?

这次不能随便立flag了,

弄个transduce差点把我坑死。。。

不过,

下次可能会遇见下面几种情况之一,

遇见一个新的道具,比如上面遇见的compose函数:

image

遇见新的秘籍或残卷,关于函数,对象,递归什么的:

image

遇见一个冒险挑战,完成某个特殊的挑战:

image

3、天辰,你说transduce设计到了很多关键知识点。。。

image

哈哈哈哈哈~

image

其他资源:

文章:

Transducers: Efficient Data Processing Pipelines in JavaScript

Understanding Transducers in JavaScript

工具库:

ramda库中的transduce

transducer.js


好了,

少侠,江湖路上,有缘再见~

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容