Reducer的深入明白

访客4年前黑客工具1226

有一些小伙伴,对JavaScript的 reduce 方式还不够明白,我们来看下面两段代码:

const nums = [1, 2, 3];
let value = 0;

for (let i = 0; i < nums.length; i++) {
    value += nums[i];
}
const nums = [1, 2, 3];
const value = nums.reduce((ac, next) => ac + next, 0);

这两段代码在功效上是等价的,都是数组中所有数字的总和,然则它们之间有一些理念差异。让我们先研究一下 reducer,由于它们功效强大,而且在编程中很主要。有成百上千篇关于 reducer 的文章,最后我会链接我喜欢的文章。


reducer 是什么

要明白 reducer 的之一点也是最主要的一点是它永远返回一个值,这个值可以是数字、字符串、数组或工具,但它始终只能是一个。reducer 对于许多场景都很适用,然则它们对于将一种逻辑应用到一组值中并最终获得一个单一效果的情形稀奇适用。

另外需要说明:reducer 本质上不会改变你的初始值;相反,它们会返回一些其他的器械。

让我们回首一下之一个例子,这样你就可以看到这里发生了什么,一起看一下下面的gif:

 

旁观gif也许对我们所有辅助,不外照样要回归代码:

const nums = [1, 2, 3];
let value = 0;

for (let i = 0; i < nums.length; i++) {
    value += nums[i];
}

数组 nums ([1,2,3]) ,数组中的每个数字的之一个值将被添加到 value (0)。我们遍历数组并将其每一项添加到 value。

让我们实验一下差别的方式来实现此功效:

const nums = [1, 2, 3];
const initialValue = 0;

const reducer = function (acc, item) { 
    return acc + item;
}

const total = nums.reduce(reducer, initialValue);

现在我们有了相同的数组,但这次我们不会改变初始值(即前段代码中的 value)。这里,我们有一个仅在更先时使用的初始值。接下来,我们可以建立一个函数,它接受一个累加器(acc)和一个项(item)。累加器是在上一次挪用中返回的累积值(或者是 initialValue),是下一个回调的输入值。在这个例子中,你可以把它想象成一个滚下一座山的雪球,当它以每一个吃过的值的巨细增进时,它会吃掉它路径中的每个值。


我们将使用 .reduce() 来吸收这个函数并从初始值更先。可以使用箭头函数简写:

const nums = [1, 2, 3];
const initialValue = 0;

const reducer = (acc, item) => { 
    return acc + item;
}

const total = nums.reduce(reducer, initialValue);

进一步缩短代码长度,我们知道箭头函数,在没有 {} 时,默认 return;

const nums = [1, 2, 3];
const initialValue = 0;

const reducer = (acc, item) => acc + item;

const total = nums.reduce(reducer, initialValue);

现在我们可以在挪用它的地方应用这个函数,也可以直接设置初始值,如下:

const nums = [1, 2, 3];

const total = nums.reduce((acc, item) => acc + item, 0);

累加器可能是一个令人生畏的术语,以是当我们在回调挪用上应用逻辑时,你可以将它想象成数组的当前状态。


挪用栈

若是不清楚发生了什么,让我们记录下每次迭代的情形。reduce 使用的回调函数将针对数组中的每个项运行。下面的演示将有助于更清楚地说明这一点。我使用了一个差别的数组([1,3,6]),由于数字与索引相同可能会令人困惑。

const nums = [1, 3, 6];

const reducer4 = function (acc, item) { 
    console.log(`Acc: ${acc}, Item: ${item}, Return value: ${acc + item}`);
    return acc + item;
}
const total4 = nums.reduce(reducer4, 0);

当我们执行这段代码时,我们会在控制台看到以下输出:

Acc: 0, Item: 1, Return value: 1
Acc: 1, Item: 3, Return value: 4
Acc: 4, Item: 6, Return value: 10

下面是一个更直观的剖析:

 

  1. 累加器(acc)从初始值(initialValue):0 更先的
  2. 然后之一个 item是1,以是返回值是1(0+1=1)
  3. 1在下次挪用时成为累加器
  4. 现在我们累加器是1(acc),item (数组的第二项)是3
  5. 返回值变为4(1+3=4)
  6. 4在下次挪用时成为累加器,挪用时的下一项 item 是6
  7. 效果是10(4+6=10),是我们的最终值,由于6是数组中的最后一项


简朴示例

既然我们已经掌握了这一点,那么让我们来看看 reducer 可以做的一些常见和有用的事情。

我们有多少个X?

假设您有一个数字数组,而且希望返回一个讲述这些数字在数组中泛起的次数的工具。请注意,这同样适用于字符串。

const nums = [3, 5, 6, 82, 1, 4, 3, 5, 82];

const result = nums.reduce((tally, amt) => {
    tally[amt] ? tally[amt]++ : tally[amt] = 1;
    return tally;
}, {});

console.log(result);
//{ '1': 1, '3': 2, '4': 1, '5': 2, '6': 1, '82': 2 }

最初,我们有一个数组和将要放入其中的工具。在 reducer 中,我们首先判断这个item是否存在于累加器中,若是是存在,加1。若是不存在,添加这一项并设置为1。最后,请返回每一项泛起的次数。然后,我们运行reduce函数,同时通报 reducer 和初始值。


获取一个数组并将其转换为显示某些条件的工具

假设我们有一个数组,我们希望基于一组条件建立一个工具。reduce 在这里异常适用!现在,我们希望从数组中随便一个数字项建立一个工具,并同时显示该数字的奇数和偶数版本。

const nums = [3, 5, 6, 82, 1, 4, 3, 5, 82];

// we're going to make an object from an even and odd
// version of each instance of a number
const result = nums.reduce((acc, item) => {
  acc[item] = {
    odd: item % 2 ? item : item - 1,
    even: item % 2 ? item + 1 : item
  }
  return acc;
}, {});

console.log(result);

控制台输出效果:

{ '1': { odd: 1, even: 2 },
  '3': { odd: 3, even: 4 },
  '4': { odd: 3, even: 4 },
  '5': { odd: 5, even: 6 },
  '6': { odd: 5, even: 6 },
  '82': { odd: 81, even: 82 } 
}

当我们遍历数组中的每一项时,我们为偶数和奇数建立一个属性,而且基于一个带模数运算符的内联条件,我们要么存储该数字,要么将其递增1。模算符异常适合这样做,由于它可以快速检查偶数或奇数 —— 若是它可以被两个整除,它是偶数,若是不是,它是奇数。


其它资源

在顶部,我提到了其他一些便利的文章,这些文章有助于更熟悉 reducer 的作用。以下是我的更爱:

  1. MDN文档对此异常有用。说真的,这是他们更好的帖子之一,他们也更详细地形貌了若是你不提供一个初始值会发生什么,我们在这篇文章中没有提到。
  2. Coding Train
  3. A Drip of JavaScript
来自:https://css-tricks.com/understanding-the-almighty-reducer/


思源资源网:分类流动

1.阿里云: 本站现在使用的是阿里云主机,平安/可靠/稳固。点击领取2000米代金券、领会最新阿里云产物的种种优惠流动点击进入

相关文章

清明节专题:献花悼念,二次元追悼大会

近两年以来,文化部,网信办等多部门联合出手 袭击盗版,色QING,暴恐动漫,非法文学出书等 涉及影视,动漫,书籍,音乐等网络多方面 深圳快播倒闭,迅雷资源屏障,百度云八秒 众多网站关闭,115...

男生灰色开衫里面穿什么(男生灰色开衫怎么搭

男生灰色开衫里面穿什么(男生灰色开衫怎么搭

经典的灰色针织开衫,是入秋的不二首选。男人的世界里没有缤纷色彩,只有简约沉稳的黑白灰,灰色带你演绎极致的低调!灰色就灰色,为什么这几年还偏偏要叫“高级灰”呢?今天就带你来看看灰色有多高级! 灰色...

网上有能查询亲戚陌陌已删聊天记录

11月10日,博威合金董事长谢识才接受央视财经记者专访,畅谈了公司通过数字化研发与数字化制造等项目,推进数字化转型,提升公司国际市场竞争力,助力“中国制造”走向世界。...

对于学生早恋你应该怎么看(花老师教你解答中学早恋)

小学早恋长短常影响本身的进修的,早恋情感背一个早恋教诲背包真的感受就像在上学的中学生呢,12岁的伊丽莎白心动了,那是一件多浪漫的工作。指导如安在海外,高中早恋我总结了几点家长为什么如此喜爱这个产物,孩...

联通手机的通话清单如何删除

韩国女团直播出事故 中国成员用衣服帮遮腿被工作人员打 韩国的韩流爱豆确实是发达,但那也产生了些隐患,像爱豆健康亮红灯,艺人被公司高层或工作人员欺负等,近日一个出道了一年的十八线女团直播出了事故。该事故...

黑客和红客(黑客和红客都是极客)

黑客和红客(黑客和红客都是极客)

本文目录一览: 1、黑客,红客,白客的区别是什么? 2、红客和黑客有什么区别? 3、黑客和红客的区别 4、什么是黑客和红客? 黑客,红客,白客的区别是什么? 黑客,红客,白客都是指计算机...