JS數(shù)組方法reduce的妙用分享
1. 基本用法
reduce()
是 JavaScript 中一個(gè)很有用的數(shù)組方法,MDN 對(duì)其解釋如下:
reduce() 方法對(duì)數(shù)組中的每個(gè)元素按序執(zhí)行一個(gè) reducer 函數(shù),每一次運(yùn)行 reducer 會(huì)將先前元素的計(jì)算結(jié)果作為參數(shù)傳入,最后將其結(jié)果匯總為單個(gè)返回值。
reduce()
方法的語法如下:
array.reduce(reducer,?initialValue)
其中有兩個(gè)參數(shù):(1)reducer 函數(shù),包含四個(gè)參數(shù):
previousValue:
上一次調(diào)用 callbackFn 時(shí)的返回值。在第一次調(diào)用時(shí),若指定了初始值 initialValue,其值則為 initialValue,否則為數(shù)組索引為 0 的元素 array[0]。currentValue:
數(shù)組中正在處理的元素。在第一次調(diào)用時(shí),若指定了初始值 initialValue,其值則為數(shù)組索引為 0 的元素 array[0],否則為 array[1]。currentIndex:
數(shù)組中正在處理的元素的索引。若指定了初始值 initialValue,則起始索引號(hào)為 0,否則從索引 1 起始。array:
用于遍歷的數(shù)組。
(2)initialValue
可選 作為第一次調(diào)用 callback 函數(shù)時(shí)參數(shù) previousValue 的值。若指定了初始值 initialValue,則 currentValue 則將使用數(shù)組第一個(gè)元素;否則 previousValue 將使用數(shù)組第一個(gè)元素,而 currentValue 將使用數(shù)組第二個(gè)元素。
下面是一個(gè)使用reduce()
求數(shù)組元素之和的例子:
const?arr?=?[0,?1,?2,?3,?4]; const?calculateSum?=?(previousValue,?currentValue)?=>?{ ????console.log('previousValue:?',?previousValue); ????console.log('currentValue:',?currentValue); ????return?previousValue?+?currentValue; }; arr.reduce(calculateSum)
reducer 會(huì)逐個(gè)遍歷數(shù)組元素,每一步都將當(dāng)前元素的值與上一步的計(jì)算結(jié)果相加(上一步的計(jì)算結(jié)果是當(dāng)前元素之前所有元素的總和),直到?jīng)]有更多的元素被相加。
這段代碼的輸出如下:
其執(zhí)行過程如下:
當(dāng)我們給reduce()
方法一個(gè)初始值12時(shí):
arr.reduce(calculateSum,?12);
其執(zhí)行過程如下:
如果數(shù)組為空且未提供初始值,reduce() 方法就會(huì)拋出 TypeError:
const?reducer?=?(accumulator,?currentValue)?=>?accumulator?+?currentValue; const?result?=?[].reduce(reducer) console.log(result)
輸出結(jié)果如下:
2. 使用技巧
(1)數(shù)組求和
reduce()
方法最直接的用法就是對(duì)數(shù)組元素求和:
const?total?=?[34,?12,?143,?13,?76].reduce( ??(previousValue,?currentValue)?=>?previousValue?+?currentValue, ??0 ); console.log(total);
其輸出結(jié)果如下:
278
(2)扁平數(shù)組
reduce()
方法還可以用來扁平化數(shù)組:
const?array?=?[[0,?1],?[2,?3],?[4,?5],?[5,?6]]; const?flattenedArray?=?array.reduce( ??(previousValue,?currentValue)?=>?previousValue.concat(currentValue), ??[] ); console.log(flattenedArray);
輸出結(jié)果如下:
[0, 1, 2, 3, 4, 5, 5, 6]
如果數(shù)組有不止一層嵌套數(shù)組,可以遞歸調(diào)用 reduce 函數(shù)來扁平化,然后將它們與最終的數(shù)組連接起來即可。
const?nestedArray?=?[[1,?[2,?3]],?[4,?5],?[[6,?7],?[8,?9]]]; function?flattenArray(nestedArray)?{ ??return?nestedArray.reduce( ????(accumulator,?currentValue)?=>? ??????accumulator.concat( ????????Array.isArray(currentValue)???flattenArray(currentValue)?:?currentValue ??????), ????[]); } const?flattenedArray?=?flattenArray(nestedArray); console.log(flattenedArray)
輸出結(jié)果如下:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
(3)數(shù)組分組
假設(shè)有一個(gè)國(guó)家對(duì)象數(shù)組,根據(jù)國(guó)家所在洲對(duì)數(shù)組中的每個(gè)國(guó)家進(jìn)行分組??梢允褂?reduce 方法來完成:
cosnt?countries?=?[ ????{name:?"Germany",?continent:?"Europe"}, ????{name:?"Brazil",?continent:?"South?America"}, ????{name:?"India",?continent:?"Asia"}, ????{name:?"France",?continent:?"Europe"}, ????{name:?"South?Korea",?continent:?"Asia"}, ] const?groupedCountries?=?countries.reduce( ??(groupedCountries,?country)?=>?{ ????if?(!groupedCountries[country.continent]){ ??????groupedCountries[country.continent]?=?[] ????} ????groupedCountries[country.continent].push(country) ????return?groupedCountries ??}, ??{} ); console.log(groupedCountries)
輸出結(jié)果如下:
(4)使用 reduce() 代替 filter().map()
在 Javascript 中,數(shù)組的 filter 方法可以通過回調(diào)過濾數(shù)組中的元素,map 方法可以通過回調(diào)內(nèi)部傳遞的邏輯使用舊數(shù)組創(chuàng)建一個(gè)新數(shù)組。有時(shí)我們必須同時(shí)使用這兩種方法,對(duì)某些條件過濾的結(jié)果創(chuàng)建一個(gè)新數(shù)組。
可以使用 reduce 方法來完成相同的工作,這樣就只需要遍歷數(shù)組一次。例如,要?jiǎng)?chuàng)建一個(gè)大于 30 的數(shù)字的平方根數(shù)組,使用 filter().map() 可能會(huì)這么寫:
const?numbers?=?[3,?21,?34,?121,?553,?12,?53,?5,?42,?11]; const?newArray?=?numbers.filter(number?=>?number?>?30).map(number?=>?Math.sqrt(number));
使用 reduce 實(shí)現(xiàn):
const?numbers?=?[3,?21,?34,?121,?553,?12,?53,?5,?42,?11]; const?newArray?=?numbers.reduce((previousValue,?currentValue)?=>?{ ??if?(currentValue?>?30)?{ ????previousValue.push(Math.sqrt(currentValue)) ??} ??return?previousValue },?[]); console.log(newArray);
輸出結(jié)果如下:
[5.830951894845301, 11, 23.515952032609693, 7.280109889280518, 6.48074069840786]
(5)統(tǒng)計(jì)數(shù)組元素出現(xiàn)次數(shù)
可以使用reduce
來統(tǒng)計(jì)數(shù)組中每個(gè)元素出現(xiàn)的次數(shù):
const?colors?=?['green',?'red',?'red',?'yellow',?'red',?'yellow',?'green',?'green']; const?colorMap?=?colors.reduce((previousValue,?currentValue)?=>?{ ????previousValue[currentValue]?>=?1???previousValue[currentValue]++?:?previousValue[currentValue]?=?1; ????return?previousValue; ??},? ??{} ); console.log(colorMap);
輸出結(jié)果如下:
{green: 3, red: 3, yellow: 2}
(6)串行執(zhí)行異步函數(shù)
有一組需要串行執(zhí)行的異步函數(shù),可以使用reduce()
來調(diào)用執(zhí)行:
const?functions?=?[ ??async?function()?{?return?1;?}, ??async?function()?{?return?2;?}, ??async?function()?{?return?3;?} ]; const?res?=?await?functions.reduce((promise,?fn)?=>?promise.then(fn),?Promise.resolve()); console.log(res);??//?輸出結(jié)果:3
這里的 res 就相當(dāng)于執(zhí)行了:
Promise.resolve().then(fn1).then(fn2).then(fn3);
(7)創(chuàng)建管道
假設(shè)有一組簡(jiǎn)單的數(shù)學(xué)函數(shù),這些函數(shù)允許我們?cè)黾印p少、加倍和減半:
function?increment(input)?{?return?input?+?1;} function?decrement(input)?{?return?input?—?1;?} function?double(input)?{?return?input?*?2;?} function?halve(input)?{?return?input?/?2;?}
如果想對(duì)一個(gè)值進(jìn)行多次上述操作,就可以使用reduce()
。管道是用于將某些初始值轉(zhuǎn)換為最終值的函數(shù)列表的術(shù)語。我們只需將執(zhí)行過程中每一步用到函數(shù)寫在管道數(shù)組中即可。
const?pipeline?=?[increment,?double,?decrement]; const?result?=?pipeline.reduce((total,?func)?=>?{ ??return?func(total); },?5); console.log(result)?//?輸出結(jié)果:11
(8)反轉(zhuǎn)字符串
可以使用reduce()
實(shí)現(xiàn)字符串的反轉(zhuǎn):
const?str?=?'hello?world'; [...str].reduce((a,v)?=>?v?+?a);??//?輸出結(jié)果:'dlrow olleh'
(9)數(shù)組去重
有一個(gè)包含重復(fù)項(xiàng)的數(shù)組,可以使用 reduce()
來對(duì)數(shù)組進(jìn)行去重:
const?arr?=?["??",?"??",?"??",?"??"]; const?dedupe?=?(acc,?currentValue)?=>?{ ??if?(!acc.includes(currentValue))?{ ????acc.push(currentValue); ??} ??return?acc; }; const?dedupedArr?=?arr.reduce(dedupe,?[]);? console.log(dedupedArr);??//?["??",?"??"];
其執(zhí)行過程如下:
當(dāng) reduce 方法遍歷數(shù)組時(shí),回調(diào)函數(shù)將應(yīng)用于數(shù)組中的每一項(xiàng)。它會(huì)檢查累加器中是否缺少當(dāng)前值,如果是,則將當(dāng)前值 push 到累加器中。
注:此示例僅用于說明 reduce 方法的工作原理,在實(shí)踐中,通常會(huì)選擇使用 Set 對(duì)數(shù)組進(jìn)行去重,這是一種性能更高的方法:
dedupedArr?=?[...new?Set(array)];
到此這篇關(guān)于JS數(shù)組方法reduce的妙用分享的文章就介紹到這了,更多相關(guān)JS reduce內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript中reduce()方法的使用詳解
- js中的reduce()函數(shù)講解
- 詳解JavaScript中數(shù)組的reduce方法
- 詳解JS數(shù)組Reduce()方法詳解及高級(jí)技巧
- js數(shù)組方法reduce經(jīng)典用法代碼分享
- JS使用reduce()方法處理樹形結(jié)構(gòu)數(shù)據(jù)
- JavaScript中自帶的 reduce()方法使用示例詳解
- JavaScript中reduce()的5個(gè)基本用法示例
- JavaScript中reduce()詳解及使用方法
- JavaScript中的reduce方法執(zhí)行過程、使用場(chǎng)景及進(jìn)階用法
相關(guān)文章
JS實(shí)現(xiàn)點(diǎn)擊拉拽輪播圖pc端移動(dòng)端適配
本文通過實(shí)例代碼給大家介紹了JS點(diǎn)擊拉拽輪播圖pc端移動(dòng)端適配 ,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09js 實(shí)現(xiàn)在離開頁面時(shí)提醒未保存的信息(減少用戶重復(fù)操作)
在離開頁面時(shí)判斷是否有未保存的輸入值,然后進(jìn)行提醒,接下來介紹實(shí)現(xiàn)步驟,感興趣的朋友可以了解下2013-01-01利用原生的JavaScript實(shí)現(xiàn)簡(jiǎn)單拼圖游戲
拼圖游戲是我們大家都玩過的一款小游戲,下面這篇文章主要給大家介紹了關(guān)于如何利用原生的JavaScript實(shí)現(xiàn)簡(jiǎn)單拼圖游戲的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-11-11微信小程序數(shù)據(jù)監(jiān)聽器使用實(shí)例詳解
這篇文章主要介紹了微信小程序數(shù)據(jù)監(jiān)聽器使用實(shí)例,數(shù)據(jù)監(jiān)聽器用于監(jiān)聽和響應(yīng)任何屬性和數(shù)據(jù)字段的變化,從而執(zhí)行特定的操作。它的作用類似于vue中的watch偵聽器2023-04-04javascript 支持鏈?zhǔn)秸{(diào)用的異步調(diào)用框架Async.Operation
javascript 支持鏈?zhǔn)秸{(diào)用的異步調(diào)用框架Async.Operation2009-08-08小程序云開發(fā)教程如何使用云函數(shù)實(shí)現(xiàn)點(diǎn)贊功能
這篇文章主要為大家詳細(xì)介紹了小程序云開發(fā)教程如何使用云函數(shù)實(shí)現(xiàn)點(diǎn)贊功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05基于JavaScript實(shí)現(xiàn)全屏透明遮罩div層鎖屏效果
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)全屏透明遮罩div層鎖屏效果的相關(guān)資料,需要的朋友可以參考下2016-01-01