亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

Javascript數組方法reduce的妙用之處分享

2024-05-06 16:51:58
字體:
來源:轉載
供稿:網友

前言

Javascript數組方法中,相比map、filter、forEach等常用的迭代方法,reduce常常被我們所忽略,今天一起來探究一下reduce在我們實戰開發當中,能有哪些妙用之處,下面從reduce語法開始介紹。

語法

array.reduce(function(accumulator, arrayElement, currentIndex, arr), initialValue)

若傳入初始值,accumulator首次迭代就是初始值,否則就是數組的第一個元素;后續迭代中將是上一次迭代函數返回的結果。所以,假如數組的長度為n,如果傳入初始值,迭代次數為n;否則為n-1。

比如實現數組 arr = [1,2,3,4] 求數組的和

let arr = [1,2,3,4];arr.reduce(function(pre,cur){return pre + cur}); // return 10

實際上reduce還有很多重要的用法,這是因為累加器的值可以不必為簡單類型(如數字或字符串),它也可以是結構化類型(如數組或對象),這使得我們可以用它做一些其他有用的事情,比如:

  • 將數組轉換為對象
  • 展開更大的數組
  • 在一次遍歷中進行兩次計算
  • 將映射和過濾函數組合
  • 按順序運行異步函數

將數組轉化為對象

在實際業務開發中,你可能遇到過這樣的情況,后臺接口返回的數組類型,你需要將它轉化為一個根據id值作為key,將數組每項作為value的對象進行查找。

例如:

const userList = [ { id: 1, username: 'john', sex: 1, email: 'john@163.com' }, { id: 2, username: 'jerry', sex: 1, email: 'jerry@163.com' }, { id: 3, username: 'nancy', sex: 0, email: '' }];

如果你用過lodash這個庫,使用_.keyBy這個方法就能進行轉換,但用reduce也能實現這樣的需求。

function keyByUsernameReducer(acc, person) { return {...acc, [person.id]: person};}const userObj = peopleArr.reduce(keyByUsernameReducer, {});console.log(userObj);

將小數組展開成大數組

試想這樣一個場景,我們將一堆純文本行讀入數組中,我們想用逗號分隔每一行,生成一個更大的數組名單。

const fileLines = [ 'Inspector Algar,Inspector Bardle,Mr. Barker,Inspector Barton', 'Inspector Baynes,Inspector Bradstreet,Inspector Sam Brown', 'Monsieur Dubugue,Birdy Edwards,Inspector Forbes,Inspector Forrester', 'Inspector Gregory,Inspector Tobias Gregson,Inspector Hill', 'Inspector Stanley Hopkins,Inspector Athelney Jones'];function splitLineReducer(acc, line) { return acc.concat(line.split(/,/g));}const investigators = fileLines.reduce(splitLineReducer, []);console.log(investigators);// [// "Inspector Algar",// "Inspector Bardle",// "Mr. Barker",// "Inspector Barton",// "Inspector Baynes",// "Inspector Bradstreet",// "Inspector Sam Brown",// "Monsieur Dubugue",// "Birdy Edwards",// "Inspector Forbes",// "Inspector Forrester",// "Inspector Gregory",// "Inspector Tobias Gregson",// "Inspector Hill",// "Inspector Stanley Hopkins",// "Inspector Athelney Jones"// ]

我們從長度為5的數組開始,最后得到一個長度為16的數組。

另一種常見增加數組的情況是flatMap,有時候我們用map方法需要將二級數組展開,這時可以用reduce實現扁平化

例如:

Array.prototype.flatMap = function(f) { const reducer = (acc, item) => acc.concat(f(item)); return this.reduce(reducer, []);}const arr = ["今天天氣不錯", "", "早上好"]const arr1 = arr.map(s => s.split(""))// [["今", "天", "天", "氣", "不", "錯"],[""],["早", "上", "好"]]const arr2 = arr.flatMap(s => s.split(''));// ["今", "天", "天", "氣", "不", "錯", "", "早", "上", "好"]

在一次遍歷中進行兩次計算

有時我們需要對數組進行兩次計算。例如,我們可能想要計算數字列表的最大值和最小值。我們可以通過兩次通過這樣做:

const readings = [0.3, 1.2, 3.4, 0.2, 3.2, 5.5, 0.4];const maxReading = readings.reduce((x, y) => Math.max(x, y), Number.MIN_VALUE);const minReading = readings.reduce((x, y) => Math.min(x, y), Number.MAX_VALUE);console.log({minReading, maxReading});// {minReading: 0.2, maxReading: 5.5}

這需要遍歷我們的數組兩次。但是,有時我們可能不想這樣做。因為.reduce()讓我們返回我們想要的任何類型,我們不必返回數字。我們可以將兩個值編碼到一個對象中。然后我們可以在每次迭代時進行兩次計算,并且只遍歷數組一次:

const readings = [0.3, 1.2, 3.4, 0.2, 3.2, 5.5, 0.4];function minMaxReducer(acc, reading) { return {  minReading: Math.min(acc.minReading, reading),  maxReading: Math.max(acc.maxReading, reading), };}const initMinMax = { minReading: Number.MAX_VALUE, maxReading: Number.MIN_VALUE,};const minMax = readings.reduce(minMaxReducer, initMinMax);console.log(minMax);// {minReading: 0.2, maxReading: 5.5}

將映射和過濾合并為一個過程

還是先前那個用戶列表,我們希望找到沒有電子郵件地址的人的用戶名,返回它們用戶名用逗號拼接的字符串。一種方法是使用兩個單獨的操作:

  • 獲取過濾無電子郵件后的條目
  • 獲取用戶名并拼接

將它們放在一起可能看起來像這樣:

function notEmptyEmail(x) { return !!x.email}function notEmptyEmailUsername(a, b) { return a ? `${a},${b.username}` : b.username}const userWithEmail = userList.filter(notEmptyEmail);const userWithEmailFormatStr = userWithEmail.reduce(notEmptyEmailUsername, '');console.log(userWithEmailFormatStr);// 'john,jerry'

現在,這段代碼是完全可讀的,對于小的樣本數據不會有性能問題,但是如果我們有一個龐大的數組呢?如果我們修改我們的reducer回調,那么我們可以一次完成所有事情:

function notEmptyEmail(x) { return !!x.email}function notEmptyEmailUsername(usernameAcc, person){ return (notEmptyEmail(person))  ? (usernameAcc ? `${usernameAcc},${person.username}` : `${person.username}`) : usernameAcc;}const userWithEmailFormatStr = userList.reduce(notEmptyEmailUsername, '');console.log(userWithEmailFormatStr);// 'john,jerry'

在這個版本中,我們只遍歷一次數組,一般建議使用filter和map的組合,除非發現性能問題,才推薦使用reduce去做優化。

按順序運行異步函數

我們可以做的另一件事.reduce()是按順序運行promises(而不是并行)。如果您對API請求有速率限制,或者您需要將每個prmise的結果傳遞到下一個promise,reduce可以幫助到你。

舉一個例子,假設我們想要為userList數組中的每個人獲取消息。

function fetchMessages(username) { return fetch(`https://example.com/api/messages/${username}`)  .then(response => response.json());}function getUsername(person) { return person.username;}async function chainedFetchMessages(p, username) { // In this function, p is a promise. We wait for it to finish, // then run fetchMessages(). const obj = await p; const data = await fetchMessages(username); return { ...obj, [username]: data};}const msgObj = userList .map(getUsername) .reduce(chainedFetchMessages, Promise.resolve({})) .then(console.log);// {glestrade: [ … ], mholmes: [ … ], iadler: [ … ]}

async函數返回一個 Promise 對象,可以使用then方法添加回調函數。當函數執行的時候,一旦遇到await就會先返回,等到異步操作完成,再接著執行函數體內后面的語句。

請注意,在此我們傳遞Promise作為初始值Promise.resolve(),我們的第一個API調用將立即運行。

下面是不使用async語法糖的版本

function fetchMessages(username) { return fetch(`https://example.com/api/messages/${username}`)  .then(response => response.json());}function getUsername(person) { return person.username;}function chainedFetchMessages(p, username) { // In this function, p is a promise. We wait for it to finish, // then run fetchMessages(). return p.then((obj)=>{  return fetchMessages(username).then(data=>{   return {    ...obj,    [username]: data   }  }) })}const msgObj = peopleArr .map(getUsername) .reduce(chainedFetchMessages, Promise.resolve({})) .then(console.log);// {glestrade: [ … ], mholmes: [ … ], iadler: [ … ]}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美最顶级的aⅴ艳星| 日韩欧美a级成人黄色| 久久久精品一区| 精品国产一区二区三区久久久狼| 成人美女免费网站视频| 91国产美女在线观看| 久久久久久久久久久亚洲| 亚洲专区中文字幕| 国产亚洲精品美女| 日韩av高清不卡| 欧美亚洲视频在线观看| 亚洲码在线观看| 久久精品国产免费观看| 2018国产精品视频| 国产一区二区视频在线观看| 国产亚洲aⅴaaaaaa毛片| 97久久超碰福利国产精品…| 欧美—级a级欧美特级ar全黄| 伊人久久久久久久久久久久久| 深夜福利国产精品| 亚洲成人精品视频在线观看| 4438全国亚洲精品在线观看视频| 国产精品国产福利国产秒拍| 国产男女猛烈无遮挡91| 性色av香蕉一区二区| 国产aⅴ夜夜欢一区二区三区| 国产精品手机播放| 亚洲国产另类 国产精品国产免费| 热门国产精品亚洲第一区在线| 国产精品流白浆视频| 亚洲色图狂野欧美| 91在线视频精品| 国产精品偷伦免费视频观看的| 欧美福利视频在线| 一区二区三区久久精品| 久久久亚洲网站| 欧美一区二区三区艳史| 成人日韩在线电影| 91在线视频免费| 亚洲欧美另类在线观看| 国产亚洲欧美日韩美女| 欧美电影在线观看| 国产日韩精品视频| 中文日韩在线观看| 国产精品中文字幕在线| 最新69国产成人精品视频免费| 亚洲性线免费观看视频成熟| 91最新在线免费观看| 亚洲精品美女网站| 日韩免费看的电影电视剧大全| 国产精品国产三级国产aⅴ浪潮| 精品女同一区二区三区在线播放| 色爱av美腿丝袜综合粉嫩av| 亚洲午夜色婷婷在线| 国产成人综合精品| 69av在线视频| 亚洲人成欧美中文字幕| 亚洲成人网久久久| 亚洲一区二区三区乱码aⅴ| 亚洲一区二区免费| 欧美在线视频一二三| 久久全国免费视频| 欧美午夜性色大片在线观看| 3344国产精品免费看| 久久九九精品99国产精品| 亚洲电影免费观看高清完整版| 日韩美女视频免费在线观看| 亚洲第一色在线| 一个人www欧美| 国产成+人+综合+亚洲欧美丁香花| 亚洲国产精品久久久久秋霞不卡| 91精品久久久久久久久久| 91久久精品国产91久久| 一本一本久久a久久精品综合小说| 97成人在线视频| 日韩精品视频免费专区在线播放| 国产国语刺激对白av不卡| 色悠悠国产精品| 国产精品尤物福利片在线观看| 日本欧美精品在线| 亚洲已满18点击进入在线看片| 国产精品私拍pans大尺度在线| 亚洲影院在线看| 久久久久久999| 色伦专区97中文字幕| 久热在线中文字幕色999舞| 欧美日韩中文字幕在线| 久久精品一本久久99精品| 欧美大胆a视频| 亚洲精品一区中文| 日韩精品在线观看网站| 91视频国产精品| 91精品国产综合久久久久久久久| 色综合五月天导航| 国产精品亚洲自拍| yellow中文字幕久久| 欧美大片免费观看在线观看网站推荐| 亚洲va男人天堂| 久久九九有精品国产23| 在线成人一区二区| 北条麻妃一区二区在线观看| 欧美日韩成人黄色| 久久久成人精品视频| 国产亚洲福利一区| 91免费看片网站| 欧美丝袜一区二区三区| 国产精品com| 97久久精品视频| 久久久精品久久久| 国产精品天天狠天天看| 欧美成人在线免费视频| 成人黄色av网| 中日韩午夜理伦电影免费| 久久久久久久97| 久久精品视频网站| 中文字幕成人精品久久不卡| 91精品国产91久久久久久不卡| 精品呦交小u女在线| 亚洲一区www| 欧美激情一二区| 欧美放荡办公室videos4k| 久热精品视频在线观看| 欧美伊久线香蕉线新在线| 国产一区二区在线播放| 亚洲国产成人精品久久| 大荫蒂欧美视频另类xxxx| 色偷偷av亚洲男人的天堂| 亚洲国产精品va在看黑人| 亚洲欧美日韩成人| 国产国产精品人在线视| 欧美精品久久久久| 国产一区二中文字幕在线看| 国产亚洲免费的视频看| 日韩av成人在线观看| 亚洲综合日韩在线| 精品二区三区线观看| 欧美日韩国产中文精品字幕自在自线| 成人情趣片在线观看免费| 亚洲午夜av久久乱码| 欧美大尺度在线观看| 久久激情视频免费观看| 欧美成人免费观看| 精品久久久久久亚洲国产300| 555www成人网| 欧美一级淫片播放口| 欧美日韩亚洲一区二区| 欧美成年人视频| 久久久久久免费精品| 日韩av网址在线| 成人精品久久久| 日本精品在线视频| 中国人与牲禽动交精品| 欧美噜噜久久久xxx| 91免费的视频在线播放| 欧美专区在线视频| 一区二区三区美女xx视频| 成人国产亚洲精品a区天堂华泰| 精品国产老师黑色丝袜高跟鞋| 亚洲精品永久免费| 亚洲一级黄色av| 亚洲japanese制服美女| 一区二区福利视频| 秋霞av国产精品一区| 亚洲一区美女视频在线观看免费|