数组reduce函数,数组求和reduce

  数组reduce函数,数组求和reduce

  作为ES5中新的常规数组方法之一,reduce是一种强有力的方法。本文介绍了25数组化简的高级用法。

  Reduce是ES5中新的常规数组方法之一。相比forEach、filter、map,实际使用中似乎忽略了一些。发现身边的人很少使用,导致这个强大的方法逐渐被埋没。

  如果经常用reduce,怎么能这么轻易放过!我还是要把它从灰尘里拿出来擦干净,把它的高级用法呈现给大家。这么有用的方法不应该被大众埋没。

  下面是对reduce语法的简要描述。具体可参考MDN中reduce()的相关描述。

  定义:对数组中的每个元素执行一个自定义累加器,将其结果汇总成单个返回值形式:array.reduce((t,v,I,a)={},Init)参数callback:回调函数(必选)initValue: initValue(可选)参数total(t):累加器计算后的返回值(必选)value(v):当前元素(必选)010-必选index(必选用累加器处理V,累加V到T的映射结果,结束这个循环,返回T进入下一个循环,重复上述操作,直到数组的最后一个元素遍历完毕。返回最终treduce的本质是积累我们举个简单的栗子,看看reduce的计算结果。

  const arr=[3,5,1,4,2];

  const a=arr.reduce((t,v)=t v);

  //相当于

  const b=arr.reduce((t,v)=t v,0);

  Reduce本质上是一个累加器函数,通过自定义累加器累加数组成员,得到一个由累加器生成的值。另外,reduce还有个弟弟,reduceRight。两种方法的功能其实是一样的,只是reduce按升序执行,reduceRight按降序执行。

  对空数组调用reduce()和reduceRight()不会执行其回调函数。可以认为reduce()对于空数组是无效的

高级用法

  仅凭上面这个简单的栗子不足以解释reduce是什么。为了展示reduce的魅力,我提供了25个场景来应用reduce的高级用法。一些高级用法可能需要与其他方法结合使用,这为reduce的多样化提供了更多的可能性。

  有些示例代码可能写得有些粗俗。如果不习惯,可以整理成自己习惯的写法array

  函数累加(.vals

  return vals.reduce((t,v)=t v,0);

  }

  函数乘法(.vals

  return vals.reduce((t,v)=t * v,1);

  }积累(1,2,3,4,5);//15

  乘法(1,2,3,4,5);//120把上一次输出的值作为下一次输入的值

  常数分数=[

  {分数:90,科目:‘语文’,权重:0.5 },

  {分数:95,科目:“数学”,权重:0.3 },

  {分数:85,科目:“英语”,权重:0.2 }

  ];

  const result=scores.reduce((t,v)=t v.score * v.weight,0);//90.5累加累乘

  函数反转(arr=[]) {

  return arr.reduceRight((t,v)=(t.push(v),t),[]);

  }Reverse([1,2,3,4,5]);//[5, 4, 3, 2, 1]权重求和

  const arr=[0,1,2,3];

  //而不是映射:[0,2,4,6]

  const a=arr . map(v=v * 2);

  const b=arr.reduce((t,v)=[.t,v * 2],[]);

  //而不是筛选器:[2,3]

  const c=arr . filter(v=v 1);

  const d=arr.reduce((t,v)=v 1?[.t,v] : t,[]);

  //而不是映射和过滤器:[4,6]

  const e=arr.map(v=v * 2)。滤波器(v=v 2);

  const f=arr.reduce((t,v)=v * 2 2?[.t,v * 2] : t,[]);代替reverse

  常数分数=[

  {分数:45,主题:“中文”},

  {分数:90,科目:“数学”},

  {分数:60,科目:“英语”}

  ];

  //而不是一些:至少有一个门是合格的

  const isatleastonequalized=scores . reduce((t,v)=t v.score=60,false);//真

  //而不是every: all限定

  const isAllQualified=scores . reduce((t,v)=t v.score=60,true);//false代替map和filter

  函数块(arr=[],size=1) {

  返回长度是多少?arr.reduce((t,v)=(t[t.length - 1]).长度===大小?t.push([v]) : t[t.length - 1].push(v),t),[[]]):[];

  }const arr=[1,2,3,4,5];

  Chunk(arr,2);//[[1, 2], [3, 4], [5]]代替some和every

  函数差(arr=[],oarr=[]) {

  return arr.reduce((t,v)=(!oarr.includes(v) t.push(v),t),[]);

  }const arr1=[1,2,3,4,5];

  const arr2=[2,3,6]

  差(arr1,arr 2);//[1, 4, 5]数组分割

  函数填充(arr=[],val= ,start=0,end=arr.length) {

  if(start 0 start=end end arr。长度)返回arrive)

  返回[

  .arr.slice(0,start),

  .数组切片(开始,结束)。reduce((t,v)=(t.push(val v),t),[]),

  .数组切片(结束,数组长度)

  ];

  }const arr=[0,1,2,3,4,5,6];

  Fill(arr, aaa ,2,5);//[0,1, aaa , aaa ,5,6]数组过滤

  函数Flat(arr=[]) {

  return arr.reduce((t,v)=t.concat(Array.isArray(v)?平(五) :五),[])

  }const arr=[0,1,[2,3],[4,5,[6,7],[8,[9,10,[11,12]];

  平坦(arr);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]数组填充

  函数Uniq(arr=[]) {

  return arr.reduce((t,v)=t.includes(v)?t : [.t,v],[]);

  }const arr=[2,1,0,3,2,1,2];

  uniq(arr);//[2, 1, 0, 3]数组扁平

  函数Max(arr=[]) {

  return arr.reduce((t,v)=t v?t:v);

  }

  函数Min(arr=[]) {

  return arr.reduce((t,v)=t v?t:v);

  }const arr=[12,45,21,65,38,76,108,43];

  max(arr);//108

  min(arr);//12数组去重

  函数Unzip(arr=[]) {

  return arr.reduce(

  (t,v)=(v.forEach((w,i)=t[i]).push(w))、t),

  Array.from({长度:Math.max(.arr.map(v=v.length)) }).映射(v=[])

  );

  } const arr=[ a ,1,true],[b ,2,false]];

  解压(arr);//[[a , b],[1,2],[真,假]]数组最大最小值

  函数计数(arr=[]) {

  return arr.reduce((t,v)=(t[v]=(t[v] 0) 1,t),{ });

  }const arr=[0,1,1,2,2,2];

  计数(arr);//{ 0: 1, 1: 2, 2: 3 }此方法是字符统计和单词统计的原理,入参时把字符串处理成数组即可数组成员独立拆解

  函数位置(arr=[],val) {

  return arr.reduce((t,v,i)=(v===val t.push(i),t),[]);

  }const arr=[2,1,5,4,2,1,6,6,7];

  位置(arr,2);//[0, 4]数组成员个数统计

  函数组(arr=[],key) {

  回车键?arr.reduce((t,v)=(!t[v[key]] (t[v[key]]=[],t[v[key]].push(v),t),{ }):{ };

  }常量数组=[

  {地区:“GZ”,姓名: YZW ,年龄:27 },

  {地区:“GZ”,姓名:“TYJ”,年龄:25 },

  {地区: SZ ,姓名: AAA ,年龄:23 },

  {面积: FS ,姓名: BBB ,年龄:21 },

  {区域: SZ ,名称: CCC ,年龄:19 }

  ];//以地区区域作为分组依据

  Group(arr, area );//{ GZ:数组(二)、SZ:数组(2),FS:数组(1) }数组成员位置记录

  函数关键字(arr=[],keys=[]) {

  return keys.reduce((t,v)=(arr。some(w=w . includes(v))t . push(v),t),[]);

  }const text=[

  今天天气真好,我想出去钓鱼,

  我一边看电视,一边写作业,

  小明喜欢同桌的小红,又喜欢后桌的小君,真铥花心,

  最近上班喜欢摸鱼的人实在太多了,代码不好好写,在想入非非

  ];

  常数关键字=[偷懒, 喜欢, 睡觉, 摸鱼, 真好, 一边, 明天];

  关键词(文本,关键词);//[喜欢, 摸鱼, 真好, 一边]数组成员特性分组

  函数ReverseStr(str=) {

  返回str.split( ).reduceRight((t,v)=t v);

  }const str=reduce最牛逼;

  反向str(str);//逼牛最ecuder数组成员所含关键字统计

  函数千分位数(数字=0) {

  const str=( num).toString().拆分(.);

  const int=nums=nums.split( ).反转()。reduceRight((t,v,i)=t (i % 3?v : `${v},`), ).replace(/^,,$/g,“);

  const dec=nums=nums.split( ).reduce((t,v,i)=t ((i 1) % 3?v : `${v},`), ).replace(/^,,$/g,“);

  return str.length 1?` ${int(str[0])} .$ { dec(str[1])} `:int(str[0]);

  } ThousandNum(1234);//1,234

  千分位数(1234.00);//1,234

  千分位数(0.1234);//0.123,4

  千分位数(1234.5678);//1,234.567,8字符串翻转

  异步函数AsyncTotal(arr=[]) {

  return arr.reduce(async(t,v)={

  const at=await t;

  const Todo=await Todo(v);

  at[v]=todo;

  返回时间:

  },答应。解析({ });

  }常数结果=await异步总计();//需要在异步非同步(异步)包围下使用数字千分化

  函数Fibonacci(len=2) {

  const arr=[.新数组(莱恩).keys()];

  return arr.reduce((t,v,i)=(i 1 t.push(t[i - 1] t[i - 2]),t),[0,1]);

  }斐波那契(10);//[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]异步累计

  函数ParseUrlSearch() {

  返回location.search.replace(/(^\?)($)/g, ).拆分("")。减少((t,v)={

  const [key,val]=v . split(=);

  t[key]=decodeURIComponent(val);

  return t;

  }, {});

  }//假设统一资源定位器为:https://www.baidu.com?年龄=25岁姓名=TYJ

  ParseUrlSearch();//{年龄: 25 ,姓名: TYJ }斐波那契数列

  函数StringifyUrlSearch(search={}) {

  返回对象.条目(搜索)。减少(

  (t,v)=` $ { t } $ { v[0]}=$ { encodeURIComponent(v[1])} `,

  对象.键(搜索)。长度??:

  ).替换(/$/, );

  }StringifyUrlSearch({年龄:27,姓名: YZW });//?age=27name=YZWURL参数反序列化

  函数GetKeys(obj={},keys=[]) {

  返回Object.keys(obj).减少((t,v)=(键。包括(v)(t[v]=obj[v]),t),{ });

  }const target={ a: 1,b: 2,c: 3,d:4 };

  常数关键字=[a , d ];

  GetKeys(target,keyword);//{ a: 1,d: 4 }URL参数序列化

  const people=[

  {地区:“GZ”,姓名: YZW ,年龄:27 },

  {地区: SZ ,姓名:“TYJ”,年龄:25 }

  ];

  const map=people.reduce((t,v)={

  const { name,rest }=v;

  t[name]=rest;

  return t;

  }, {});//{ YZW: {…},TYJ: {…} }返回对象指定键值

  函数合成(.funs) {

  if (funs.length===0) {

  返回arg=arg

  }

  if (funs.length===1) {

  return funs[0];

  }

  return funs.reduce((t,v)=(.arg)=t(v(.arg)));

  }

兼容和性能

   好用是挺好用的,但是兼容性如何呢?在犬科动物上搜索一番,兼容性绝对的好,可大胆在任何项目上使用。不要吝啬你的想象力,尽情发挥减少的构成技能啦。对于时常做一些累计的功能,减少绝对是首选方法。

  另外,有些同学可能会问,减少的性能又如何呢?下面我们通过对for、forEach、map和减少四个方法同时做1~100000的累加操作,看看四个方法各自的执行时间。

  //创建一个长度为100000的数组

  常量列表=[.新数组(100000)。keys()];

  //对于

  console.time(for ).

  设结果1=0;

  对于(设I=0;i list.lengthi ) {

  结果1=11

  }

  console.log(结果1);

  控制台。时间结束(“for”);

  //forEach

  console.time(forEach ).

  设结果2=0;

  列表。foreach(v=(结果2=v 1));

  console.log(结果2);

  控制台。时间结束(“forEach”);

  //地图

  控制台。时间(“地图”);

  设结果3=0;

  list.map(v=(result3=v 1,v));

  console.log(结果3);

  控制台。时间结束(“map”);

  //减少

  控制台。时间(减少);

  const result4=list.reduce((t,v)=t v 1,0);

  console.log(结果4);

  控制台。时间结束( reduce );累加操作执行时间数组转对象6.79970703125毫秒Redux Compose函数原理3.6960449604以上代码在MacBook Pro 2019 15寸16G内存512克闪存的铬79下执行,不同的机器不同的环境下执行以上代码都有可能存在差异。

  我已同时测试过多台机器和多个浏览器,连续做了10次以上操作,发现减少总体的平均执行时间还是会比其他三个方法稍微快一点,所以大家还是放心使用啦!本文更多是探讨减少的使用技巧,如对减少的兼容和性能存在疑问,可自行参考相关资料进行验证。

  最后,送大家一张减少生成的乘法口诀表:一七得七,二七四十八,三八妇女节,五一劳动节,六一儿童节。

  更多编程相关知识,请访问:编程视频!以上就是值得了解的25个数组减少高级用法的详细内容,更多请关注我们其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: