讓人欲罷不能的 reduce(內含小編項目實戰(zhàn)示例)
(給程序員成長指北加星標,提升前端技能)
轉自:掘金 -?憤怒的黃牛
https://juejin.cn/post/6921975823612248077
以前遇到復雜一點的數(shù)據結構處理時,for循環(huán)套for循環(huán)兩梭子,代碼篇幅大幅度增加,隔壁工位哥們看了不忍心了,說reduce那么好用為啥不用呢?菜雞小編也不敢多問reduce怎么用,悄悄的下去查資料。而后分享給各位‘工友們’。
1. reduce到底是何方神圣
arr.reduce(callback,[initialValue])
reduce 為數(shù)組中的每一個元素依次執(zhí)行回調函數(shù),不包括數(shù)組中被刪除或從未被賦值的元素,接受四個參數(shù):初始值(或者上一次回調函數(shù)的返回值),當前元素值,當前索引,調用 reduce 的數(shù)組。
callback(執(zhí)行arr中的每一個元素的函數(shù),包含四個參數(shù))
previousValue?(上一次調用回調返回的值,或者是提供的初始值(initialValue))
currentValue?(數(shù)組中的當前元素)
index?(數(shù)組當前元素的索引)
array?(調用reduce的當前數(shù)組)
initialValue?(初始值)(可選參數(shù))
!注意:如果沒有寫initialValue參數(shù)的話,reduce的callback會從arr的索引為1的元素開始執(zhí)行,反之的話,會從索引為0的元素開始執(zhí)行callback
2. reduce的簡單到復雜
基本操作
let?arr?=?[1,2,3]
const?count?=?(arr)?=>?{
????return?arr.reduce((pre,cur,index,array)?=>?{
????????return?pre?+?cur
????},0)?
}
count(arr)?//?6
reduce造輪子--forEach
Array.prototype.myForEach?=?function?(fn)?{
??return?this.reduce((acc,cur,index,arr)?=>?{
????fn(cur,index)
??})
}
arr.myForEach((item,index)?=>?{
??console.log(item,index)
})
利用原型掛載的原理,接受一個回調函數(shù)fn(就是myForEach的傳入函數(shù)),利用reduce的原理調用傳入的fn(),執(zhí)行fn里面的一些數(shù)據操作。
reduce造輪子--map
const?arr?=?[1,2,3]
const?arr1?=?[4,5]
Array.prototype.myMap?=?function(fn,?thisArg)?{
??const?result?=?[];
??this.reduce((prev,?curr,?index,?array)?=>?{
????result[index]?=?fn.call(thisArg,?array[index],?index,?array);
??},?0)
??return?result;
}
arr.myMap(function(c,i)?{
????return?c?+?i?+?this.length
},arr1)
//?[3,5,7]
同理利用原型掛載的原理,傳入map的函數(shù),在原理的myMap函數(shù)的reduce函數(shù)中執(zhí)行,利用第二個thisArg參數(shù),再在reduce里面調用回調函數(shù)的時候call傳入,改變myMap函數(shù)的this指向,將myMap函數(shù)的函數(shù)體執(zhí)行結果,緩存在result數(shù)組中,返回出來。類似的filter,find,findIndex等思路都是一樣的
reduce實踐1-8
//?p?為成員1,2,3,ps為成員的成績,其中p和ps一一對應
//?求?每個成員的分數(shù)列表?{1:?[1,2,2],2:?[2,2,2],?3:?[3,3,3]}
const?p?=?[3,?3,?1,?2,?2,?1,?3,?2]
const?ps?=?[69,?71,?93,?79,?81,?93,?77,?99]
const?res?=?(p,ps)?=>?{
??????return?p.reduce((cur,?pre,?index)?=>?{
??????if?(!cur[pre])?{
????????cur[pre]?=?[];
??????}
??????for?(let?i?=?0;?i?????????if?(index?===?i)?{
??????????cur[pre].push(ps[i]);
????????}
??????}
??????return?cur
????},?{})
????};
console.log(res(p,ps));
?//?按照年齡進行分組?{18:?[],19:?[],?20:?[]}
?const?arr?=?[
????{name:?'小孫',?age:?18,?score:?60,?weight:?60},
????{name:?'小王',?age:?19,?score:?70,?weight:?55},
????{name:?'小李',?age:?18,?score:?60,?weight:?70},
????{name:?'小劉',?age:?20,?score:?70,?weight:?65},
????{name:?'小趙',?age:?18,?score:?60,?weight:?60},
????{name:?'小錢',?age:?19,?score:?70,?weight:?55},
????{name:?'小周',?age:?20,?score:?60,?weight:?50},
????]
??const?groupBy?=?(arr,?key)?=>?{
??????return?arr.reduce((pre,cur)?=>?{
????????pre[cur[key]]?=?pre[cur[key]]?||?[]
????????pre[cur[key]].push(cur)
????????return?pre
??????},?{})
????}
??console.log(groupBy(arr,?'age'))
//?扁平化數(shù)組
????const?c?=?[[1,2,3],[4,5,[6,7]]]
????const?flatMap?=?(arr)?=>?{
??????return?arr.reduce((pre,item)?=>?{
????????return?pre.concat(Array.isArray(item)???flatMap(item):?item)
??????},[])
????}
????console.log(flatMap(c))
?//?字符串大小寫區(qū)別????
????const?str?=?'abCD'
????const?change?=?(str)?=>?{
??????let?arr?=?str.split('')
??????return?arr.reduce((pre,cur)?=>?{
????????if?(cur?===?cur.toLowerCase())?{
??????????pre.push(cur.toUpperCase())
????????}?else?{
??????????pre.push(cur.toLowerCase())
????????}
????????return?pre
??????},[])
????}
????console.log(change(str).join())
//?找數(shù)組中的公共元素
????const?arr10?=?[1,2,3,4]
????const?arr2?=?[6,4,7,8,3]
????const?arr3?=?[0,9,4,3]
????const?getOnly?=?(...arr)?=>?{
??????return?arr.reduce((pre,next)?=>?{
????????return?pre.filter(c?=>?next.includes(c))
??????},arr[0])
????}
????console.log(getOnly(arr10,arr2,arr3))
//?查找字符串中每個字符出現(xiàn)的次數(shù)????
????const?str1?=?'jgdsgdlkgj'
????const?op?=?str1.split('').reduce((pre,next)=>?{
??????pre[next]??pre[next]++:?pre[next]=1
??????return?pre
????},{})
????console.log(op)
//?查找公共前綴
????const?strArr?=?["flower","flow","flight"]
????const?getStr?=?(strs)?=>?{
????????return?strs.reduce((pre,next)?=>?{
????????????while?(!next.startsWith(pre))?{
????????????????pre?=?pre.substring(0,pre.length-1)
????????????}
????????????return?pre
????????},strs[0])
????}
????console.log(getStr(strArr))
//?數(shù)組對象去重
?const?onlyList?=?(arr)?=>?{
??????return?arr.reduce((pre,cur,index)?=>?{
????????if(pre.find(c?=>?c.from?===?cur.from?&&?c.to?===?cur.to))?{
??????????return?pre
????????}?else?{
??????????return?[...pre,cur]
????????}
??????},?[])
????}
console.log(onlyList(quieArr))

結語
小編從一個reduce一無所知的菜雞,通過各方搜索資料,項目中的多方實踐,只為讓代表變得簡潔方便。希望小編的這些總結能對各位工友們有一丟丟的幫助,也不枉小編把自己筆記本的總結分享出來了。
1.看到這里了就點個在看支持下吧,你的「點贊,在看」是我創(chuàng)作的動力。
2.關注公眾號
程序員成長指北,回復「1」加入高級前端交流群!「在這里有好多 前端?開發(fā)者,會討論?前端 Node 知識,互相學習」!3.也可添加微信【ikoala520】,一起成長。
“在看轉發(fā)”是最大的支持
