0

代码写得好,Reduce 方法少不了,我用这10例子来加深学习!

 2 years ago
source link: https://segmentfault.com/a/1190000040727275
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

代码写得好,Reduce 方法少不了,我用这10例子来加深学习!

发布于 11 月 18 日

作者:Ramgen
译者:前端小智
来源:dev

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

数组中的 reduce 犹如一只魔法棒,通过它可以做一些黑科技一样的事情。语法如下:

reduce(callback(accumulator, currentValue[, index, array])[,initialValue])

reduce 接受两个参数,回调函数和初识值,初始值是可选的。回调函数接受4个参数:积累值、当前值、当前下标、当前数组。

如果 reduce的参数只有一个,那么积累值一开始是数组中第一个值,如果reduce的参数有两个,那么积累值一开始是出入的 initialValue 初始值。然后在每一次迭代时,返回的值作为下一次迭代的 accumulator 积累值。

今天的这些例子的大多数可能不是问题的理想解决方案,主要的目的是想说介绍如何使用reduce来解决问题。

求和和乘法

// 求和
[3, 5, 4, 3, 6, 2, 3, 4].reduce((a, i) => a + i);
// 30

// 有初始化值
[3, 5, 4, 3, 6, 2, 3, 4].reduce((a, i) => a + i, 5 );
// 35

// 如果看不懂第一个的代码,那么下面的代码与它等价
[3, 5, 4, 3, 6, 2, 3, 4].reduce(function(a, i){return (a + i)}, 0 );

// 乘法
[3, 5, 4, 3, 6, 2, 3, 4].reduce((a, i) => a * i);

查找数组中的最大值

如果要使用 reduce 查找数组中的最大值,可以这么做:

[3, 5, 4, 3, 6, 2, 3, 4].reduce((a, i) => Math.max(a, i), -Infinity);

上面,在每一次迭代中,我们返回累加器和当前项之间的最大值,最后我们得到整个数组的最大值。

如果你真想在数组中找到最大值,不要有上面这个,用下面这个更简洁:

Math.max(...[3, 5, 4, 3, 6, 2, 3, 4]);

连接不均匀数组

let data = [
  ["The","red", "horse"],
  ["Plane","over","the","ocean"],
  ["Chocolate","ice","cream","is","awesome"], 
  ["this","is","a","long","sentence"]
]
let dataConcat = data.map(item=>item.reduce((a,i)=>`${a} ${i}`))

// 结果
['The red horse', 
'Plane over the ocean', 
'Chocolate ice cream is awesome', 
'this is a long sentence']

在这里我们使用 map 来遍历数组中的每一项,我们对所有的数组进行还原,并将数组还原成一个字符串。

移除数组中的重复项

let dupes = [1,2,3,'a','a','f',3,4,2,'d','d']
let withOutDupes = dupes.reduce((noDupes, curVal) => {
  if (noDupes.indexOf(curVal) === -1) { noDupes.push(curVal) }
  return noDupes
}, [])

检查当前值是否在累加器数组上存在,如果没有则返回-1,然后添加它。

当然可以用 Set 的方式来快速删除重复值,有兴趣的可以自己去谷歌一下。

[..."(())()(()())"].reduce((a,i)=> i==='('?a+1:a-1,0);
// 0

[..."((())()(()())"].reduce((a,i)=> i==='('?a+1:a-1,0);
// 1

[..."(())()(()()))"].reduce((a,i)=> i==='('?a+1:a-1,0);
// -1

这是一个很酷的项目,之前在力扣中有刷到。

按属性分组

let obj = [
  {name: 'Alice', job: 'Data Analyst', country: 'AU'},
  {name: 'Bob', job: 'Pilot', country: 'US'},
  {name: 'Lewis', job: 'Pilot', country: 'US'},
  {name: 'Karen', job: 'Software Eng', country: 'CA'},
  {name: 'Jona', job: 'Painter', country: 'CA'},
  {name: 'Jeremy', job: 'Artist', country: 'SP'},
]
let ppl = obj.reduce((group, curP) => {
  let newkey = curP['country']
  if(!group[newkey]){
    group[newkey]=[]
  }
  group[newkey].push(curP)
  return group
}, [])

这里,我们根据 country 对第一个对象数组进行分组,在每次迭代中,我们检查键是否存在,如果不存在,我们创建一个数组,然后将当前的对象添加到该数组中,并返回组数组。

你可以用它做一个函数,用一个指定的键来分组对象。

let flattened = [[3, 4, 5], [2, 5, 3], [4, 5, 6]].reduce(
  (singleArr, nextArray) => singleArr.concat(nextArray), [])

// 结果:[3, 4, 5, 2, 5, 3, 4, 5, 6]

这只是一层,如果有多层,可以用递归函数来解决,但我不太喜欢在 JS 上做递归的东西😂。

一个预定的方法是使用.flat方法,它将做同样的事情

[ [3, 4, 5],
  [2, 5, 3],
  [4, 5, 6]
].flat();

只有幂的正数

[-3, 4, 7, 2, 4].reduce((acc, cur) => {
  if (cur> 0) {
    let R = cur**2;
    acc.push(R);
  }
  return acc;
}, []);

// 结果
[16, 49, 4, 144]

反转字符串

const reverseStr = str=>[...str].reduce((a,v)=>v+a)

这个方法适用于任何对象,不仅适用于字符串。调用reverseStr("Hola"),输出的结果是aloH

二进制转十进制

const bin2dec = str=>[...String(str)].reduce((acc,cur)=>+cur+acc*2,0)

// 等价于

const bin2dec = (str) => {
  return [...String(str)].reduce((acc,cur)=>{
    return +cur+acc*2
  },0)
}

为了说明这一点,让我们看一个例子:(10111)->1+(1+(1+(0+(1+0*2)*2)*2)*2)*2

~完,我是刷碗智,励志等退休后,要回家摆地摊的人,我们下期见!


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

原文:https://dev.to/ramgendepy/lea...

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq44924588... 已收录,有一线大厂面试完整考点、资料以及我的系列文章。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK