当前位置: 首页 > 科技观察

20个实用的JavaScript片段,让你成为更好的开发者

时间:2023-03-11 22:01:26 科技观察

开发者每天面临的几乎所有问题都可以通过解决一个定义明确的问题的一组更小的解决方案来解决。这些解决方案最好被描述为“纯函数”。尽管这些函数中的大多数都在不同的库中实现,但了解如何以及何时将难题分解为更小的问题非常重要。这种解决问题的心态会提高我们的开发效率,让我们成为更好的开发者。在今天的文章中,我无序地分享了我经常用来解决各种问题的20个有用的“纯函数”,希望对你也有用。接下来,让我们开始吧。1.GetValue给定一个对象或数组,该函数将返回指定路径的值,否则为null。constgetValue=(obj,path)=>path.replace(/\[([^[\]]*)]/g,'.$1.').split('.').filter(prop=>prop!=='').reduce((prev,next)=>(previnstanceofObject?prev[next]:undefined),obj);getValue({a:{b:c:'d'}},'a.b.C');//=dgetValue({a:{b:c:[1,2]}},'a.b.c[1]');//=22,Clamp确保值在指定范围内,否则“钳制”到最接近的最小值和最大值。constclamp=(min,max,value)=>{if(min>max)thrownewError('min不能大于max');返回值<最小值?最小值:值>最大值?最大值:值;}}钳位(0、10、-5);//=0clamp(0,10,20);//=103.Sleep在执行下一个操作之前等待指定的持续时间(以毫秒为单位)。constsleep=async(duration)=>(newPromise(resolve=>setTimeout(resolve,duration)));等待睡眠(1000);//等待1sec4,GroupBy根据键控函数和索引对对象中的相关项进行分组。constgroupBy=(fn,list)=>(list.reduce((prev,next)=>({...prev,[fn(next)]:[...(prev[fn(next)]||[]),next]}),{}));groupBy(vehicle=>vehicle.make,[{make:'tesla',model:'3'},{make:'tesla',model:'y'},{make:'ford',model:'mach-e'},]);//{//tesla:[{make:'tesla',...},{make:'tesla',...}],//ford:[{make:'ford',...}],//}5.CollectBy根据键控函数创建包含相关项的子列表。importgroupByfrom'./groupBy';constcollectBy=(fn,list)=>Object.values(groupBy(fn,list));collectBy(vehicle=>vehicle.make,[{make:'tesla',model:'3'},{make:'tesla',model:'y'},{make:'ford',model:'mach-e'},]);//[//[{make:'tesla',...},{make:'tesla',...}],//[{make:'ford',...}],//]6.Head获取列表的第一个元素。此函数对于编写干净且可读的代码很有用。consthead=list=>list[0];head([1,2,3]);//=1head([]);//=undefined7,Tail获取列表中除第一个元素之外的所有元素。此函数对于编写干净且可读的代码很有用。consttail=list=>list.slice(1);tail([1,2,3]);//=[2,3]尾巴([]);//=[]8,Flatten递归地从嵌套子列表中提取所有项目以创建一个平面列表。constflatten=list=>list.reduce((prev,next)=>([...prev,...(Array.isArray(next)?flatten(next):[next])]),[]);展平([[1,2,[3,4],5,[6,[7,8]]]]);//=[1,2,3,4,5,6,7,8]9.IntersectionBy找到键控函数定义的两个列表中存在的所有值。constintersectionBy=(fn,listA,listB)=>{constb=newSet(listB.map(fn);returnlistA.filter(val=>b.has(fn(val)));};intersectionBy(v=>v,[1,2,3],[2,3,4]);//=[2,3]intersectionBy(v=>v,[{a:1},{a:2}],[{a:2},{a:3},{a:4}]);//=[{a:2}];10.IndexBy对列表索引中的每个元素执行key函数确定的值.constindexBy=(fn,list)=>list.reduce((prev,next)=>({...prev,[fn(next)]:next},{});indexBy(val=>val.a,[{a:1},{a:2},{a:3}]);//={1:{a:1},2:{a:2},3:{a:3}}11.DifferenceBy查找第一个列表中不存在于第二个列表中的所有项,由键控函数确定importindexByfrom'./indexBy';constdifferenceBy=(fn,listA,listB)=>{constbIndex=indexBy(fn,listb);返回listA.filter(val=>!bIndex[fn(val)]);});differenceBy(val=>val,[1,2,3],[3,4,5]);//=[1,2]differenceBy(vehicle=>vehicle.make,[{make:'tesla'},{make:'ford'},{make:'gm'}],[{make:'tesla'},{make:'bmw'},{make:'audi'}],);//=[{make:'ford'},{make:'gm'}]12,RecoverWithif如果给定的函数抛出错误,则返回默认值。constrecoverWith=async(defaultValue,fn,...args)=>{try{constresult=awaitfn(...args);返回结果;}catch(_e){返回默认值;}}recoverWith('A',val=>val,'B');//=BrecoverWith('A',()=>{thrownewError()});//='A'13,Distance计算两点p1和p2之间的距离。constdistance=([x0,y0],[x1,y1])=>(Math.hypot(x1-x0,y1-y0));距离([0,1],[5,4]);//=5.830951894845314,DropWhile从列表中删除元素,从第一个元素开始,直到满足som谓词。constdropWhile=(pred,list)=>{让索引=0;list.every(elem=>{index++;returnpred(elem);});返回list.slice(index-1);}dropWhile(val=>(val<5),[1,2,3,4,5,6,7]);//=[5,6,7]15,SumBy给定某个函数,该函数为每个元素生成一个单独的值,计算列表中所有元素的总和。constsumBy=(fn,列表)=>列表。reduce((prev,next)=>prev+fn(next),0);sumBy(product=>product.price,[{name:'pizza',price:10},{name:'pepsi',price:5},{name:'salad',price:5},]);//=2016,Ascending给定一个评估函数,创建一个升序比较器函数。constascending=(fn)=>(a,b)=>{constvalA=fn(a);constvalB=fn(b);返回valAvalB?1:0;}constbyPrice=ascending(val=>val.price);[{price:300},{price:100},{price:200}].sort(byPrice);//=[{price:100},{price:200},{price:300}]17.降序给定一个评估函数,创建一个降序比较函数。constdescending=(fn)=>(a,b)=>{constvalA=fn(b);constvalB=fn(a);返回valAvalB?1:0;}constbyPrice=descending(val=>val.price);[{price:300},{price:100},{price:200}].sort(byPrice);//=[{price:300},{price:200},{price:100}]18.FindKey在索引中找到满足给定谓词的第一个键值。constfindKey=(predicate,index)=>Object.keys(index).find(key=>predicate(index[key],key,index));findKey(car=>!car.available,{特斯拉:{可用:true},ford:{available:false},gm:{available:true}},);//="ford"19、BifurcateBy将给定列表的值拆分为两个列表,一个包含谓词函数,一个值为真,另一个包含假。constbifurcateBy=(predicate,list)=>列表。reduce((acc,val,i)=>(acc[predicate(val,i)?0:1].push(val),acc),[[],[]]);bifurcateBy(val=>val>0,[-1,2,-3,4]);//=[[2,4],[-1,-3]]20,Pipe从左到右执行函数组合。所有额外的参数都将传递给列表中的第一个函数,因此可以有任何数量。结果将在第二个中传递,第二个的结果将传递给第三个,...以此类推,直到处理完所有函数。constpipe=(functions,...args)=>(functions.reduce((prev,next)=>Array.isArray(prev)?next(...prev):next(prev),args));管道([Math.abs,Math.floor,val=>-val],4.20);//=-4pipe([(a,b)=>a-b,Math.abs],5,10);//=5最后的想法虽然所有这些特征对于帮助我们解决我们正在处理的问题都非常有用,但最重要的是我们知道如何分解复杂和困难的问题,以便每个定义明确的小问题都可以解决独立解决。一旦掌握了这个解决问题的小技巧,您就可以成为一名优秀的开发人员!如果您觉得我今天分享的内容对您有帮助,请点赞关注我。同时把这篇文章分享给身边做开发的朋友,或许对他有帮助。最后,感谢阅读,祝编程愉快!