日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
JavaScript數(shù)組reduce總是不會(huì)用?看看這5個(gè)例子就懂了!

相信不少初學(xué)者曾經(jīng)都被 JavaScript 數(shù)組的 reduce方法困擾過(guò),一直搞不明白到底怎么用。reduce方法是按順序?qū)?shù)組每個(gè)元素執(zhí)行某個(gè)函數(shù),這個(gè)函數(shù)接收上一次執(zhí)行結(jié)果作為參數(shù),并將結(jié)果傳給下一次調(diào)用。reduce方法用得好可以簡(jiǎn)化復(fù)雜的邏輯,提高代碼可讀性。通過(guò)下面幾個(gè)例子可以幫你快速理解reduce的用法。

1.數(shù)字?jǐn)?shù)組求和

這是reduce最常見(jiàn)的入門級(jí)例子。如果用傳統(tǒng)的for循環(huán)是這樣的:

 
 
 
 
  1. function sum(arr) { 
  2.   let sum = 0; 
  3.   for (const val of arr) { 
  4.     sum += val; 
  5.   } 
  6.   return sum; 
  7.  
  8. sum([1, 3, 5, 7]); // 16 

如果用 reduce():

 
 
 
 
  1. function sum(arr) { 
  2.   const reducer = (sum, val) => sum + val; 
  3.   const initialValue = 0; 
  4.   return arr.reduce(reducer, initialValue); 
  5.  
  6. sum([1, 3, 5, 7]); // 16 

reduce()函數(shù)的第一個(gè)參數(shù)是一個(gè)reducer函數(shù),第二個(gè)參數(shù)是初始值。在每個(gè)數(shù)組元素上執(zhí)行reducer函數(shù),第一個(gè)參數(shù)是“累進(jìn)值”。累進(jìn)值的初始值是initialValue,并且在每一輪調(diào)用后更新為reducer函數(shù)的返回值。

為了幫助理解,可以用for循環(huán)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的reduce()函數(shù):

 
 
 
 
  1. function reduce(arr, reducer, initialValue) { 
  2.   let accumulator = initialValue; 
  3.   for (const val of array) { 
  4.     accumulator = reducer(accumulator, val); 
  5.   } 
  6.   return accumulator; 

2.對(duì)象數(shù)組數(shù)字屬性值求和

單看 reduce() 本身,大家更多的感受是它的晦澀難懂,而不是有多好用。如果僅僅是為了給數(shù)字?jǐn)?shù)組求和,用for循環(huán)可能來(lái)得更直觀。但是,當(dāng)你把它跟其他數(shù)組方法(比如filter和map)結(jié)合使用時(shí),才能感受到它的強(qiáng)大和方便。

舉個(gè)栗子,假設(shè)有個(gè)對(duì)象數(shù)組,每個(gè)對(duì)象都有個(gè)total屬性。對(duì)這些total求和:

 
 
 
 
  1. const lineItems = [ 
  2.   { description: 'Eggs (Dozen)', quantity: 1, price: 3, total: 3 }, 
  3.   { description: 'Cheese', quantity: 0.5, price: 5, total: 2.5 }, 
  4.   { description: 'Butter', quantity: 2, price: 6, total: 12 } 
  5. ]; 

用reduce可以這樣寫:

 
 
 
 
  1. lineItems.reduce((sum, li) => sum + li.total, 0); // 17.5 

這樣是能得到最終結(jié)果,但是代碼的可組合性就沒(méi)那么好,可以做些優(yōu)化,把total屬性提前提取出來(lái):

 
 
 
 
  1. lineItems.map(li => li.total).reduce((sum, val) => sum + val, 0); 

第二種方式為什么更好?因?yàn)檫@樣就可以把求和的邏輯抽象到一個(gè)單獨(dú)的函數(shù)sum()中,方便以后重用。

 
 
 
 
  1. //匯總 total  
  2. lineItems.map(li => li.total).reduce(sumReducer, 0); 
  3.  
  4. //  匯總 quantity 
  5. lineItems.map(li => li.quantity).reduce(sumReducer, 0); 
  6.  
  7. function sumReducer(sum, val) { 
  8.   return sum + val; 

這種抽象比較重要,因?yàn)槟阌X(jué)得 sumReducer() 邏輯不會(huì)變,其實(shí)不然。比如,這個(gè)求和邏輯并沒(méi)有考慮到0.1 + 0.2 !== 0.3的問(wèn)題。(參考 為什么 0.1 + 0.2 = 0.300000004)如果有了這個(gè)抽象,要修復(fù)這個(gè)缺陷就比較方便了。比如:

 
 
 
 
  1. const { round } = require('lodash'); 
  2.  
  3. function sumReducer(sum, val) { 
  4.   // 保留2位小數(shù) 
  5.   return _.round(sum + val, 2); 

3.求最大值

reduce()通常用來(lái)求和,但它的功能遠(yuǎn)不止這個(gè)。累進(jìn)值accumulator 可以是任意值:數(shù)字,null,undefined,數(shù)組,對(duì)象等。

舉個(gè)栗子,假設(shè)有個(gè)日期數(shù)組,要找出最近的一個(gè)日期:

 
 
 
 
  1. const dates = [ 
  2.   '2019/06/01', 
  3.   '2018/06/01', 
  4.   '2020/09/01', // 這個(gè)是最近日期,但是怎么找到它? 
  5.   '2018/09/01' 
  6. ].map(v => new Date(v)); 

一種方法是給數(shù)組排序,找最后一個(gè)值??瓷先タ尚?,但是效率沒(méi)那么高,并且用數(shù)組的默認(rèn)方法給日期對(duì)象排序其實(shí)是有點(diǎn)小問(wèn)題的。不只是日期對(duì)象,任何類型的值在sort()方法中比較,都會(huì)默認(rèn)先轉(zhuǎn)成字符串比較,最終結(jié)果可能并不是你想要的。

 
 
 
 
  1. const a = [4,1,13,2]; 
  2. // 驚不驚喜,意不意外? 
  3. a.sort(); // [1, 13, 2, 4] 

這里就可以用reduce()來(lái)處理:

 
 
 
 
  1. // 這里是用 `>` 和`<` 比較日期對(duì)象,因此不會(huì)有問(wèn)題 
  2. const maxDate = dates.reduce((max, d) => d > max ? d : max, dates[0]); 

4.分組計(jì)數(shù)

假設(shè)有個(gè)對(duì)象數(shù)組,每個(gè)對(duì)象上有個(gè)age屬性:

 
 
 
 
  1. const characters = [ 
  2.   { name: 'Tom', age: 59 }, 
  3.   { name: 'Jack', age: 29 }, 
  4.   { name: 'Bruce', age: 29 } 
  5. ]; 

怎樣返回一個(gè)對(duì)象,包含每個(gè)age的人物角色數(shù)量?比如這樣: { 29: 2, 59: 1 }.

用 reduce() 的實(shí)現(xiàn)方式如下:

 
 
 
 
  1. const reducer = (map, val) => { 
  2.   map[val] = map[val] || 1; 
  3.   ++map[val]; 
  4.   return map; 
  5. }; 
  6. characters.map(char => char.age).reduce(reducer, {}); 

5.Promise 動(dòng)態(tài)鏈?zhǔn)秸{(diào)用

假設(shè)你有一個(gè)異步函數(shù)數(shù)組,想要按順序執(zhí)行:

 
 
 
 
  1. const functions = [ 
  2.   async function() { return 1; }, 
  3.   async function() { return 2; }, 
  4.   async function() { return 3; } 
  5. ]; 

如果是靜態(tài)的Promise代碼,我們直接在代碼里鏈?zhǔn)秸{(diào)用就行了。但如果是動(dòng)態(tài)的Promise數(shù)組,可以用reduce串起來(lái):

 
 
 
 
  1. // 最后 `res`的結(jié)果等價(jià)于`Promise.resolve().then(fn1).then(fn2).then(fn3)` 
  2. const res = await functions. 
  3.   reduce((promise, fn) => promise.then(fn), Promise.resolve()); 
  4. res; // 3 

當(dāng)然,reduce 能做的事情還有很多,它本質(zhì)上是對(duì)數(shù)組元素執(zhí)行某種“累進(jìn)”操作,最終返回單個(gè)值。

本文轉(zhuǎn)載自微信公眾號(hào)「1024譯站」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系1024譯站公眾號(hào)。


新聞名稱:JavaScript數(shù)組reduce總是不會(huì)用?看看這5個(gè)例子就懂了!
當(dāng)前URL:http://m.5511xx.com/article/djscded.html