简单的解释一下arrayreduce,看完你就明白了。reduce()方法顺序执行您为数组中的每个元素提供的reducer函数。reducer的每次运行都会将前面元素的计算结果作为参数传入,最终将结果聚合成一个单一的返回值,这是官方MDN上给出的一段话。每次都会将上一次的计算结果作为下一个参数传入。这是什么意思?让我们看一个简单的例子;constsum=(arr)=>{returnarr.reduce((prev,cur)=>{returnprev+cur},0)}console.log('sum:',sum([1,2,3,4,5]))//15的结果是15,咦,求和有这么简单吗?看看之前是怎么写的;constsum2=(arr)=>{让ret=0;arr.forEach(val=>{ret+=val;})returnret}console.log('sum2:',sum2([1,2,3,4,5]))//15我们发现我们之前的方法是循环计算。reduce方法比cyclic方法代码简单很多,但是没有cyclic方法通俗易懂,下面断点分析;constsum=(arr)=>{returnarr.reduce((prev,cur)=>{debugger;returnprev+cur},0)}console.log('sum:',sum([1,2,3,4,5]))//15第一次:其实我们发现在reduce回调函数中,第一个参数prev默认为初始值0,然后cur是当前值数组每次通过循环。第一次:prev:0,cur:1,执行返回结果0+1,为第二次循环prev:1的初始值。第二次:prev:1,cur:2,执行返回结果1+2,即第三次循环的初值prev:3。...第五次:prev:10,cur:5,执行返回10+5,结束。所以我们永远记住这个通用公式。prev是第一次默认传入的值。当循环迭代下一次循环时,上次返回的结果会作为prev,cur永远是本次迭代的item。变量arr=[];constcallback=(prev,current,currentIndex,source)=>{//第一个prev=init,后续每次计算后的结果将作为下一个prev,current为当前arr的item//current:当前数组的item//currentIndex:当前索引//source原数组也是arr}arr.reduce(callback,init?)注意init是可选的,如果有值,prev默认取,然后current将其默认为第一个值。如果init没有值,那么prev是第一个值,current是第二个值。你会发现不给默认值比给默认值少了一个周期。constsum=(arr)=>{returnarr.reduce((prev,cur,currentIndex,arr)=>{console.log(prev,cur,currentIndex,arr)returnprev+cur})}console.log('sum:',sum([1,2,3,4,5]))//15//121[1,2,3,4,5]//332[1,2,3,4,5]//643[1,2,3,4,5]//1054[1,2,3,4,5]过滤数据中的指定字段数据;使用reduce过滤指定必填字段;letsourceArr=[{id:1,name:'WebTechnologyAcademy',age:18},{id:2,name:'Maic',age:20},{id:3,name:'Tom',age:16},]constret=sourceArr.reduce((prev,cur)=>{const{id,age}=cur;returnprev.concat({id,age})},[])console.log(ret);//[{id:1,age:18},{id:2,age:20},{id:3,age:16}]如果使用map,它可能看起来像这样。...constret2=sourceArr.map(v=>{return{id:v.id,age:v.age}})console.log('ret2',ret2);方面;减少如下;constsourceArr2=[[1,2,3],[4,5,6],[8,9],0]constret3=sourceArr2.reduce((prev,cur)=>{返回prev.concat(cur)},[])以前你可能有这样的东西;...constret4=sourceArr2.flat(1)或递归;varflatLoop=(source,ret=[])=>{constloop=(arr)=>{arr.forEach(v=>{if(Array.isArray(v)){loop(v)}else{ret.push(v)}})}loop(source)returnret}flatLoop(sourceArr2,[])统计一个字符出现的次数;对于每个版本;conststrCount=(arr)=>{constobj={}arr.forEach(key=>{if(keyinobj){obj[key]+=1;}else{obj[key]=1;}});returnobj}constret5=strCount(['a','a','b','c','d'])console.log('ret5',ret5)//ret5{a:2,b:1,c:1,d:1}缩减版本实现;conststrCount2=(arr)=>{返回arr.reduce((prev,cur)=>{if(curinprev){prev[cur]+=1;}else{prev[cur]=1;}returnprev},{})}console.log('ret6',strCount2(['a','a','b','c','d']))获取一个字段的所有集合大批;varpublicInfo=[{id:'1',name:'网络技术学院',age:8},{id:'2',name:'前端从进阶到入学',age:10},{id:'3',name:'前端大神',age:15},{id:'3',name:'前端之巅',age:12}]constret7=publicInfo.map(v=>v.name)console.log('ret7',ret7)减少实现;constret8=publicInfo.reduce((prev,cur)=>{returnprev.concat(cur.name)},[])console.log('ret8',ret8)重复数据删除;在你可以使用Set或循环来做之前constsourceData=['1','1','2',3,4,5,3]console.log([...newSet(sourceData)])//['1','2',3,4,5]//orconstobj={}sourceData.forEach(item=>{obj[item]=item})console.log(Object.values(obj))reduce实现去重...consyret9=sourceData.reduce((prev,cur)=>{if(prev.indexOf(cur)===-1){prev.push(cur)}returnprev},[])而不是过滤器withmap假设我们有一个场景,就是过滤掉原始数据中age>10的数据,返回对应的名字。varpublicInfo=[{id:'1',name:'网络技术学院',age:10},{id:'2',name:'前端从进阶到入学',age:10},{id:'3',name:'前端之神',age:12},{id:'3',name:'前端之巅',age:12}]constret11=publicInfo.filter(v=>v.age>10).map(v=>v.name);console.log(ret11);//['前端之神','前端之巅']我们知道上面使用filter和map有两个循环,但是reduce只需要一个循环就可以搞定。...publicInfo.reduce((prev,cur)=>{if(cur.age>10){prev.push(cur.name)}returnprev},[])更多关于reduce[1]的练习可以参考MDN文档,在项目中多实践后,一一补充。总结主要分析了reduce计算方法的特点。每次计算的结果都会作为下一个prev的初始值。第二个参数``cur`是当前循环数组的值。如果reduce给了一个初始值,那么prev就是当前传入的初始值,如果没有初始值,默认为当前数组的第一项,cur就是第二个元素。如果默认没有初值,则比给初值少一个循环。.一些例子用reduce进行了实践,巩固了reduce的一些使用特点。本文示例源代码为代码示例[2]。参考[1]reduce:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce[2]代码示例:https://github.com/maicFir/lessonNote/tree/master/javascript/22-reduce
