亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JS數(shù)組Reduce方法功能與用法實例詳解

 更新時間:2020年04月29日 11:25:07   作者:nero  
這篇文章主要介紹了JS數(shù)組Reduce方法功能與用法,結(jié)合實例形式詳細(xì)分析了JS數(shù)組Reduce方法操作數(shù)組統(tǒng)計、去重等相關(guān)操作技巧,需要的朋友可以參考下

本文實例講述了JS數(shù)組Reduce方法功能與用法。分享給大家供大家參考,具體如下:

概述

一直以來都在函數(shù)式編程的大門之外徘徊,要入門的話首先得熟悉各種高階函數(shù),數(shù)組的reduce方法就是其中之一。

reduce方法將會對數(shù)組元素從左到右依次執(zhí)行reducer函數(shù),然后返回一個累計的值。舉個形象的例子:你要組裝一臺電腦,買了主板、CPU、顯卡、內(nèi)存、硬盤、電源...這些零件是組裝電腦的必要條件。

裝的過程可以簡單概括為拆掉每個零件的包裝,再裝到一起。類比一下reduce函數(shù)就可以明白了,那些零件就相當(dāng)于要執(zhí)行reduce方法的數(shù)組,對每個零件執(zhí)行拆除包裝的加工程序,就是對數(shù)組的每個元素執(zhí)行reducer函數(shù),把這些零件裝到一起,就相當(dāng)于reduce方法的任務(wù),最終組裝好的電腦相當(dāng)于reduce方法的返回值。

reduce方法接收兩個參數(shù),第一個參數(shù)是回調(diào)函數(shù)reducer,第二個參數(shù)是初始值。reducer函數(shù)接收四個參數(shù):

  • Accumulator:MDN上解釋為累計器,但我覺得不恰當(dāng),按我的理解它應(yīng)該是截至當(dāng)前元素,之前所有的數(shù)組元素被reducer函數(shù)處理累計的結(jié)果
  • Current:當(dāng)前被執(zhí)行的數(shù)組元素
  • CurrentIndex: 當(dāng)前被執(zhí)行的數(shù)組元素索引
  • SourceArray:原數(shù)組,也就是調(diào)用reduce方法的數(shù)組

如果傳入第二個參數(shù),reduce方法會在這個參數(shù)的基礎(chǔ)上開始累計執(zhí)行。

概念講了那么多,那reduce它的執(zhí)行機(jī)制是怎樣的呢?別著急,從用法入手一點一點分析。

來個最好理解的例子:數(shù)組求和

  const arr = [1, 2, 3, 4]
  const accumulator = (total, current, currentIndex, arr) => {
   console.log(total, current, currentIndex, arr);
   return total + current
  }
  console.log(arr.reduce(accumulator))

執(zhí)行結(jié)果如下:

很明確,最終的結(jié)果就是把所有數(shù)組的元素都加起來。值得注意的是,它將數(shù)組的第一個元素作為累加的初始值,然后再依次對后邊的元素執(zhí)行reducer函數(shù)。

總共執(zhí)行了三次,得出最終結(jié)果。那如果傳入初始值,是怎樣的執(zhí)行順序?

console.log(arr.reduce(accumulator, 3))

結(jié)果如下:

這次是以傳入的初始值作為累加的起點,然后依次對數(shù)組的元素執(zhí)行reducer。

假設(shè)對沒有初始值的空數(shù)組調(diào)用reduce方法,則會報錯:

Uncaught TypeError: Reduce of empty array with no initial value

一些用法

講了一些概念,但使用場景更重要,下面來看一下reduce方法都會有哪些用途。

compose函數(shù)

compose是函數(shù)式編程的一種形式,用于將多個函數(shù)合并,上一個函數(shù)的返回值作為當(dāng)前函數(shù)的入?yún)?,?dāng)前函數(shù)的返回值再作為下一個函數(shù)的入?yún)ⅲ@樣的效果有點類似于koa中間件的洋蔥模型。

[a, b, c, d] => a(b(c(d())))

實際上和累加差不多,只不過把累加操作變成了入?yún)?zhí)行,相加的結(jié)果變成了執(zhí)行的返回值。redux的applyMiddleware內(nèi)就使用了compose,目的是保證最終的dispatch是被所有中間件處理后的結(jié)果。

下面來以applyMiddleware中的compose為例,先看用法:

const result = compose(a, b, c)(params)

執(zhí)行情況是這樣:

(params) => a(b(c(params)))

返回的是一個函數(shù),將params作為該函數(shù)的入?yún)?,被右?cè)第一個函數(shù)執(zhí)行,執(zhí)行順序是從右到左執(zhí)行,其余的函數(shù)的參數(shù)都是上一個函數(shù)的返回值。

看一下實現(xiàn):

function compose(...funcs) {
 // funcs是compose要組合的那些函數(shù),arg是componse返回的函數(shù)的參數(shù)
 if (funcs.length === 0) {
  // 如果沒有傳入函數(shù),那么直接返回一個函數(shù),函數(shù)的返回值就是傳進(jìn)來的參數(shù)
  return arg => arg
 }
 if (funcs.length === 1) {
  // 如果只傳入了一個函數(shù),直接返回這個函數(shù)
  return funcs[0]
 }

 return funcs.reduce((all, current) => {
  return (...args) => {
   return all(current(...args))
  }
 })
}

扁平化數(shù)組

const array = [[0, 1], [2, 3], [4, 5]]
const flatten = arr => {
 return arr.reduce((a, b) => {
  return a.concat(b)
 }, [])
}
console.log(flatten(array)); // [0, 1, 2, 3, 4, 5]

來看一下執(zhí)行過程,

  • 第一次執(zhí)行,初始值傳入[],走到reduce的回調(diào)里,參數(shù)a就這個[],參數(shù)b是數(shù)組第一項[0, 1],回調(diào)內(nèi)[].cancat([0, 1])
  • 第二次執(zhí)行,reduce的回調(diào)參數(shù)a是上一次回調(diào)執(zhí)行的結(jié)果[0, 1],本次繼續(xù)用它來concat數(shù)組的第二項[2, 3],得到結(jié)果[0, 1, 2, 3]作為下一次回調(diào)執(zhí)行的參數(shù)a繼續(xù)執(zhí)行下去
  • ...以此類推

那么假設(shè)數(shù)組是這樣呢?[[0, [111, 222], 1], [2, [333, [444, 555]], 3], [4, 5]],其實加個遞歸調(diào)用就可以

const array = [[0, [111, 222], 1], [2, [333, [444, 555]], 3], [4, 5]]
const flatten = arr => {
 return arr.reduce((a, b) => {
  if (b instanceof Array) {
   return a.concat(flatten(b))
  }
  return a.concat(b)
 }, [])
}
console.log(flatten(array)); // [0, 111, 222, 1, 2, 333, 444, 555, 3, 4, 5]

統(tǒng)計字符串中每個字符出現(xiàn)的次數(shù)

每次回調(diào)執(zhí)行的時候,都會往對象中加一個key為字符串,value為出現(xiàn)次數(shù)的鍵值,若已經(jīng)存儲過字符串,那么它的value加1。

const str = 'adefrfdnnfhdueassjfkdiskcddfjds'
const arr = str.split('')
const strObj = arr.reduce((all, current) => {
 if (current in all) {
  all[current]++
 } else {
  all[current] = 1
 }
 return all
}, {})

console.log(strObj)
// {"a":2,"d":7,"e":2,"f":5,"r":1,"n":2,"h":1,"u":1,"s":4,"j":2,"k":2,"i":1,"c":1}

數(shù)組去重

const arr = ['1', 'a', 'c', 'd', 'a', 'c', '1']
const afterUnique = arr.reduce((all, current) => {
 if (!all.includes(current)) {
  all.push(current)
 }
 return all
}, [])
console.log(afterUnique); // ["1", "a", "c", "d"]

按照順序調(diào)用promise

這種方式實際上處理的是promise的value,將上一個promise的value作為下一個promise的value進(jìn)行處理。

const prom1 = a => {
 return new Promise((resolve => {
  resolve(a)
 }))
}
const prom2 = a => {
 return new Promise((resolve => {
  resolve(a * 2)
 }))
}
const prom3 = a => {
 return new Promise((resolve => {
  resolve(a * 3)
 }))
}

const arr = [prom1, prom2, prom3]
const result = arr.reduce((all, current) => {
 return all.then(current)
}, Promise.resolve(10))

result.then(res => {
 console.log(res);
})

實現(xiàn)

通過上面的用法,可以總結(jié)出來reduce的特點:

  • 接收兩個參數(shù),第一個為函數(shù),函數(shù)內(nèi)會接收四個參數(shù):Accumulator Current CurrentIndex SourceArray,第二個參數(shù)為初始值。
  • 返回值為一個所有Accumulator累計執(zhí)行的結(jié)果
 Array.prototype.myReduce = function(fn, base) {
  if (this.length === 0 && !base) {
   throw new Error('Reduce of empty array with no initial value')
  }
  for (let i = 0; i < this.length; i++) {
   if (!base) {
    base = fn(this[i], this[i + 1], i, this)
    i++
   } else {
    base = fn(base, this[i], i, this)
   }
  }
  return base
 }

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容可查看本站專題:《JavaScript常用函數(shù)技巧匯總》、《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)

希望本文所述對大家JavaScript程序設(shè)計有所幫助。

相關(guān)文章

  • 按鈕JS復(fù)制文本框和表格的代碼

    按鈕JS復(fù)制文本框和表格的代碼

    有時候我們需要復(fù)制一個框的內(nèi)容或者整個表格,一般的操作很可能造成一些不方便,一是操作步驟較為復(fù)制,一是復(fù)制表格的時候容易復(fù)制不完整或者格式出錯。
    2011-04-04
  • js實現(xiàn)隨機(jī)數(shù)字字母驗證碼

    js實現(xiàn)隨機(jī)數(shù)字字母驗證碼

    這篇文章主要為大家詳細(xì)介紹了js隨機(jī)驗證碼的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 替代window.event.srcElement效果的可兼容性的函數(shù)

    替代window.event.srcElement效果的可兼容性的函數(shù)

    getEvent()方法可模擬window.event效果
    2009-12-12
  • JavaScript實現(xiàn)LI列表數(shù)據(jù)綁定的方法

    JavaScript實現(xiàn)LI列表數(shù)據(jù)綁定的方法

    這篇文章主要介紹了JavaScript實現(xiàn)LI列表數(shù)據(jù)綁定的方法,可實現(xiàn)綁定Li列表項對應(yīng)數(shù)值項的功能,涉及javascript鼠標(biāo)onmousemove、onmouseout及onclick等事件的相關(guān)使用技巧,需要的朋友可以參考下
    2015-08-08
  • javascript實現(xiàn)博客園頁面右下角返回頂部按鈕

    javascript實現(xiàn)博客園頁面右下角返回頂部按鈕

    這篇文章主要介紹了使用javascript實現(xiàn)博客園頁面右下角返回頂部按鈕的思路及源碼,非常不錯,這里推薦給小伙伴們
    2015-02-02
  • js tab欄切換代碼實例解析

    js tab欄切換代碼實例解析

    這篇文章主要介紹了js tab欄切換代碼實例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09
  • javascript實現(xiàn)滾動條效果

    javascript實現(xiàn)滾動條效果

    這篇文章主要為大家詳細(xì)介紹了javascript實現(xiàn)滾動條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • javascript給span標(biāo)簽賦值的方法

    javascript給span標(biāo)簽賦值的方法

    本篇文章通過兩種方法給大家介紹js給span標(biāo)簽賦值的方法,兩種方法都比較不錯,特此分享給大家,供大家學(xué)習(xí)
    2015-11-11
  • JS實現(xiàn)左邊列表移到到右邊列表功能

    JS實現(xiàn)左邊列表移到到右邊列表功能

    這篇文章主要介紹了JS實現(xiàn)左邊列表移到到右邊列表功能,實現(xiàn)功能主要是左邊的下拉框內(nèi)容添加到右邊的下拉框,支持多選移動,且同時將右邊的下拉框?qū)ο笠瞥?,需要的朋友可以參考?/div> 2018-03-03
  • script的async屬性以非阻塞的模式加載腳本

    script的async屬性以非阻塞的模式加載腳本

    HTML5實現(xiàn)了script的async屬性,這個新的屬性可以讓js在瀏覽器中以非阻塞的模式加載,接下來介紹如何應(yīng)用此屬性,感興趣的朋友可以了解下
    2013-01-01

最新評論