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

JavaScript30秒,从入门到放弃

时间:2023-03-12 12:22:46 科技观察

Interesting最近很火的github上的库30-seconds-of-code很有意思,代码也很优雅。可以自己学es6翻译,也可以学英文。代码美观大方。美只是功能性的表达。享受arrayGcd计算数字数组的最大公分母(gcd)。使用Array.reduce()和gcd公式(使用递归)计算数字数组的最大公分母。constarrayGcd=arr=>{constgcd=(x,y)=>!y?x:gcd(y,x%y);returnarr.reduce((a,b)=>gcd(a,b));}//arrayGcd([1,2,3,4,5])->1//arrayGcd([4,8,12])->4计算数组的*公约数。使用Array.reduce()和gcd公式(使用递归)计算数组的***公约数。?codecatarrayGcd.jsconstarrayGcd=arr=>{constgcd=(x,y)=>!y?x:gcd(y,x%y);returnarr.reduce((a,b)=>gcd(a,b));}console.log(arrayGcd([1,2,3,4,5]));console.log(arrayGcd([4,8,12]));?codenodearrayGcd.js14gcd是欧氏算法,具体不要看,自己查。这里使用了数组的reduce方法,还是比较简洁的。如果你对reduce不是很了解,可以通过看mdn来了解。arrayLcm计算数字数组的最小公倍数(lcm)。使用Array.reduce()和lcm公式(使用递归)计算数字数组的最小公倍数。constarrayLcm=arr=>{constgcd=(x,y)=>!y?x:gcd(y,x%y);constlcm=(x,y)=>(x*y)/gcd(x,y)returnrr.reduce((a,b)=>lcm(a,b));}//arrayLcm([1,2,3,4,5])->60//arrayLcm([4,8,12])->24计算一个数组的最小公倍数。使用Array.reduce()和lcm公式(使用递归)计算数组的最小公约数。?codecatarrayLcm.jsconstarrayLcm=arr=>{constgcd=(x,y)=>(!y?x:gcd(y,x%y));constlcm=(x,y)=>x*y/gcd(x,y);returnarr.reduce((a,b)=>lcm(a,b));};console.log(arrayLcm([1,2,3,4,5]));console.log(arrayLcm([4,8,12]));?codenodearrayLcm.js6024lcm算法用的是前面的gcd算法,重点是两个数的最大公约数和最小公倍数的乘积正好是这两个数的乘积.arrayMax返回数组中的最大值。使用Math.max()结合展开运算符(...)得到数组中的最大值。constarrayMax=arr=>Math.max(...arr);//arrayMax([10,1,5])->10返回数组中的最大值。使用Math.max()和ES6的扩展运算符...返回数组中的最大值。?codecatarrayMax.jsconstarrayMax=arr=>Math.max(...arr);console.log(arrayMax([10,1,5]));?codenodearrayMax.js10其实就是Math.max()做的事情,有没什么好说的。arrayMin返回数组中的最小值。使用Math.min()结合展开运算符(...)得到数组中的最小值。constarrayMin=arr=>Math.min(...arr);//arrayMin([10,1,5])->1返回数组中的最小值。将Math.min()与ES6的展开运算符一起使用...以返回数组中的最小值。?codecatarrayMin.jsconstarrayMin=arr=>Math.min(...arr);console.log(arrayMin([10,1,5]));?codenodearrayMin.js1其实就是Math.min()做的事情,有没什么好说的。chunk将数组分成指定大小的较小数组。使用Array.from()创建一个新数组,该数组适合将要生成的块数。使用Array.slice()将新数组的每个元素映射到长度为size的块。如果原始数组不能被平均分割,最后的块将包含剩余的元素。constchunk=(arr,size)=>Array.from({length:Math.ceil(arr.length/size)},(v,i)=>arr.slice(i*size,i*size+size));//分块([1,2,3,4,5],2)->[[1,2],[3,4],[5]]根据给定的大小,一个数组被分成包含大小数字的更小数组块的数组。使用Array.from()生成一个新的符合要求的数组。使用Array.slice()截取指定大小的元素,组成一个新的数组块。如果原始数组长度不能被大小整除,则最后剩下的元素将属于最后一个块。?codecatchunk.jsconstchunk=(arr,size)=>Array.from({length:Math.ceil(arr.length/size)},(v,i)=>arr.slice(i*size,i*size+size));console.log(chunk([1,2,3,4,5],2));?codenodechunk.js[[1,2],[3,4],[5]]Array.from(arrayLike,mapFn,thisArg)对于这个方法,第一个参数是类数组或可迭代对象,第二个参数是应用于每个数组元素的方法,第三个参数是将this指向上。通俗地说,就是指定谁是你的父亲。这里使用了一个{length:Math.ceil(arr.length/size)}迭代对象,length指定迭代次数,即数组的长度除以size,正好是原数组的值长度除以大小并四舍五入。四舍五入是为了满足不能完全整除的情况。比如将5个元素分成2个一组,分成两组,每组两个元素,剩下的元素成为一个独立的组,总长度为3.(v,i),因为数组在每个处都初始化为undefined迭代时的位置,v始终未定义。arr.slice(i*size,i*size+size)在迭代过程中,每次截取size元素组成一个新的数组。这里的i随着迭代而变化,比如长度为3,则i为0,1,2。这里的迭代类似于python中的range。?codepythonPython3.6.4(default,Dec232017,10:37:40)[GCC4.2.1CompatibleAppleLLVM9.0.0(clang-900.0.39.2)]ondarwinType"help","copyright","credits"or"license"formoreinformation.>>>importmath>>>arr=[1,2,3,4,5]>>>size=2>>>foriinrange(math.ceil(len(arr)/size)):...print('index:',i)...index:0index:1index:2compact从数组中移除虚假值。使用Array.filter()过滤掉虚假值(false、null、0、""、undefined和NaN).constcompact=arr=>arr.filter(Boolean);//compact([0,1,false,2,'',3,'a','e'*23,NaN,'s',34])->[1,2,3,移除数组中的假元素。(这个falsey不好翻译,不是错误的意思,而是value的布尔运算值是false的意思,我个人经常用!!来判断)。使用Array.filter()过滤掉falsey、null、0、""、undefined和NaN。?codecatcompact.jsconstcompact=arr=>arr.filter(Boolean);console.log(compact([0,1,false,2,"",3,"a","e"*23,NaN,"s",34]));?codenodecompact.js[1,2,3,'a','s',34]Array.prototype.filter()就搞定了,没什么好说的。countOccurrences计算数组中某个值的出现次数。每次遇到数组中的特定值时,使用Array.reduce()递增计数器。constcountOccurrences=(arr,value)=>arr.reduce((a,v)=>v===value?a+1:a+0,0);//countOccurrences([1,1,2,1,2,3],1)->3统计一个元素在一个元素中出现的次数阵列频率。如果指定元素在遍历过程中出现在数组中,则使用Array.reduce()增加指定元素的计数值。默认计数为0console.log(countOccurrences([1,1,2,1,2,3],1));console.log(countOccurrences([1,1,2,1,2,3],5));?codenodecountOccurrences.js30三元运算符(v===value?a+1:a+0)遍历过程中,判断遍历的数组值v是否严格等于指定的value值,是的,a的次数+1;不,a+0。***中逗号后的0为初始值,即a=0。了解reduce方法的人都知道这一点。特别地,因为这个函数必须返回一个值,如果指定的元素在数组中没有出现一次,返回值为0,所以必须初始化为0。deepFlattenDeep压平一个数组。使用递归。使用Array.concat()使用空数组([])和扩展运算符(...)来展平数组。递归地展平数组中的每个元素。constdeepFlatten=arr=>[].concat(...arr.map(v=>Array.isArray(v)?deepFlatten(v):v));//deepFlatten([1,[2],[[3],4],5])->[1,2,3,4,5]深度展平数组。使用递归方法。结合Array.concat()、空数组[]和ES6展开运算符...来展平数组。如果展平的元素仍然是一个数组,递归地使用这个方法。?codecatdeepFlatten.jsconstdeepFlatten=arr=>[].concat(...arr.map(v=>(Array.isArray(v)?deepFlatten(v):v)));console.log(deepFlatten([1,[2],[[3],4],5]));?codenodedeepFlatten.js[1,2,3,4,5]三元运算符(Array.isArray(v)?deepFlatten(v):v)判断v是否为数组,如果是,递归使用deepFlatten(五);如果不是,直接返回v。[].concat(...arr.map(fn))使用空数组进行map操作生成的数组...并将展开后的操作值拼接成一个结果数组并返回。这种方法是一种深层次的方法,很多时候都有特定的层次需求,比如下划线。实现方式是再增加一个flag参数进行处理。我不会详细谈论它。我应该可以写一个系列。今天先写到这里,明天继续。