摘要:接下來,我們可以創(chuàng)建一個函數(shù),它接受一個累加器和一個項。累加器是在上一次調(diào)用中返回的累積值或者是,是下一個回調(diào)的輸入值。在中,我們首先判斷這個是否存在于累加器中,如果是存在,加。
翻譯: 劉小夕原文鏈接:https://css-tricks.com/unders...
更多文章可戳: https://github.com/YvetteLau/...
有一些小伙伴,對JavaScript的 reduce 方法還不夠理解,我們來看下面兩段代碼:
const nums = [1, 2, 3]; let value = 0; for (let i = 0; i < nums.length; i++) { value += nums[i]; }
const nums = [1, 2, 3]; const value = nums.reduce((ac, next) => ac + next, 0);
這兩段代碼在功能上是等價的,都是數(shù)組中所有數(shù)字的總和,但是它們之間有一些理念差異。讓我們先研究一下 reducer,因為它們功能強(qiáng)大,而且在編程中很重要。有成百上千篇關(guān)于 reducer 的文章,最后我會鏈接我喜歡的文章。
reducer 是什么要理解 reducer 的第一點也是最重要的一點是它永遠(yuǎn)返回一個值,這個值可以是數(shù)字、字符串、數(shù)組或?qū)ο?,但它始終只能是一個。reducer 對于很多場景都很適用,但是它們對于將一種邏輯應(yīng)用到一組值中并最終得到一個單一結(jié)果的情況特別適用。
另外需要說明:reducer 本質(zhì)上不會改變你的初始值;相反,它們會返回一些其他的東西。
讓我們回顧一下第一個例子,這樣你就可以看到這里發(fā)生了什么,一起看一下下面的gif:
觀看gif也許對我們所有幫助,不過還是要回歸代碼:
const nums = [1, 2, 3]; let valu  let i = 0; i < nums.length; i++) { value += nums[i]; }
數(shù)組 nums ([1,2,3]) ,數(shù)組中的每個數(shù)字的第一個值將被添加到 value (0)。我們遍歷數(shù)組并將其每一項添加到 value。
讓我們嘗試一下不同的方法來實現(xiàn)此功能:
const nums = [1, 2, 3]; const initialValue = 0; const reducer = function (acc, item) { return acc + item; } const total = nums.reduce(reducer, initialValue);
現(xiàn)在我們有了相同的數(shù)組,但這次我們不會改變初始值(即前段代碼中的 value)。這里,我們有一個僅在開始時使用的初始值。接下來,我們可以創(chuàng)建一個函數(shù),它接受一個累加器(acc)和一個項(item)。累加器是在上一次調(diào)用中返回的累積值(或者是 initialValue),是下一個回調(diào)的輸入值。在這個例子中,你可以把它想象成一個滾下一座山的雪球,當(dāng)它以每一個吃過的值的大小增長時,它會吃掉它路徑中的每個值。
我們將使用 .reduce() 來接收這個函數(shù)并從初始值開始??梢允褂眉^函數(shù)簡寫:
const nums = [1, 2, 3]; const initialValue = 0; const reducer = (acc, item) => { return acc + item; } const total = nums.reduce(reducer, initialValue);
進(jìn)一步縮短代碼長度,我們知道箭頭函數(shù),在沒有 {} 時,默認(rèn) return;
const nums = [1, 2, 3]; const initialValue = 0; const reducer = (acc, item) => acc + item; const total = nums.reduce(reducer, initialValue);
現(xiàn)在我們可以在調(diào)用它的地方應(yīng)用這個函數(shù),也可以直接設(shè)置初始值,如下:
const nums = [1, 2, 3]; const total = nums.reduce((acc, item) => acc + item, 0);
累加器可能是一個令人生畏的術(shù)語,所以當(dāng)我們在回調(diào)調(diào)用上應(yīng)用邏輯時,你可以將它想象成數(shù)組的當(dāng)前狀態(tài)。
調(diào)用棧如果不清楚發(fā)生了什么,讓我們記錄下每次迭代的情況。reduce 使用的回調(diào)函數(shù)將針對數(shù)組中的每個項運(yùn)行。下面的演示將有助于更清楚地說明這一點。我使用了一個不同的數(shù)組([1,3,6]),因為數(shù)字與索引相同可能會令人困惑。
const nums = [1, 3, 6]; const reducer4 = function (acc, item) { console.log(`Acc: ${acc}, Item: ${item}, Return value: ${acc + item}`); return acc + item; } const total4 = nums.reduce(reducer4, 0);
當(dāng)我們執(zhí)行這段代碼時,我們會在控制臺看到以下輸出:
Acc: 0, Item: 1, Return value: 1 Acc: 1, Item: 3, Return value: 4 Acc: 4, Item: 6, Return value: 10
下面是一個更直觀的分解:
累加器(acc)從初始值(initialValue):0 開始的
然后第一個 item是1,所以返回值是1(0+1=1)
1在下次調(diào)用時成為累加器
現(xiàn)在我們累加器是1(acc),item (數(shù)組的第二項)是3
返回值變?yōu)?(1+3=4)
4在下次調(diào)用時成為累加器,調(diào)用時的下一項 item 是6
結(jié)果是10(4+6=10),是我們的最終值,因為6是數(shù)組中的最后一項
簡單示例既然我們已經(jīng)掌握了這一點,那么讓我們來看看 reducer 可以做的一些常見和有用的事情。
我們有多少個X?假設(shè)您有一個數(shù)字?jǐn)?shù)組,并且希望返回一個報告這些數(shù)字在數(shù)組中出現(xiàn)的次數(shù)的對象。請注意,這同樣適用于字符串。
const nums = [3, 5, 6, 82, 1, 4, 3, 5, 82]; const result = nums.reduce((tally, amt) => { tally[amt] ? tally[amt]++ : tally[amt] = 1; return tally; }, {}); console.log(result); //{ "1": 1, "3": 2, "4": 1, "5": 2, "6": 1, "82": 2 }
最初,我們有一個數(shù)組和將要放入其中的對象。在 reducer 中,我們首先判斷這個item是否存在于累加器中,如果是存在,加1。如果不存在,添加這一項并設(shè)置為1。最后,請返回每一項出現(xiàn)的次數(shù)。然后,我們運(yùn)行reduce函數(shù),同時傳遞 reducer 和初始值。
獲取一個數(shù)組并將其轉(zhuǎn)換為顯示某些條件的對象假設(shè)我們有一個數(shù)組,我們希望基于一組條件創(chuàng)建一個對象。reduce 在這里非常適用!現(xiàn)在,我們希望從數(shù)組中任意一個數(shù)字項創(chuàng)建一個對象,并同時顯示該數(shù)字的奇數(shù)和偶數(shù)版本。
const nums = [3, 5, 6, 82, 1, 4, 3, 5, 82]; // we"re going to make an object from an even and odd // version of each instance of a number const result = nums.reduce((acc, item) => { acc[item] = { odd: item % 2 ? item : item - 1, even: item % 2 ? item + 1 : item } return acc; }, {}); console.log(result);
控制臺輸出結(jié)果:
{ "1": { odd: 1, even: 2 }, "3": { odd: 3, even: 4 }, "4": { odd: 3, even: 4 }, "5": { odd: 5, even: 6 }, "6": { odd: 5, even: 6 }, "82": { odd: 81, even: 82 } }
當(dāng)我們遍歷數(shù)組中的每一項時,我們?yōu)榕紨?shù)和奇數(shù)創(chuàng)建一個屬性,并且基于一個帶模數(shù)運(yùn)算符的內(nèi)聯(lián)條件,我們要么存儲該數(shù)字,要么將其遞增1。模算符非常適合這樣做,因為它可以快速檢查偶數(shù)或奇數(shù) —— 如果它可以被兩個整除,它是偶數(shù),如果不是,它是奇數(shù)。
其它資源在頂部,我提到了其他一些便利的文章,這些文章有助于更熟悉 reducer 的作用。以下是我的最愛:
MDN文檔對此非常有用。說真的,這是他們最好的帖子之一,他們也更詳細(xì)地描述了如果你不提供一個初始值會發(fā)生什么,我們在這篇文章中沒有提到。
Coding Train
A Drip of JavaScript
謝謝各位小伙伴愿意花費寶貴的時間閱讀本文,如果本文給了您一點幫助或者是啟發(fā),請不要吝嗇你的贊和Star,您的肯定是我前進(jìn)的最大動力。 https://github.com/YvetteLau/...
關(guān)注公眾號,加入技術(shù)交流群。文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106488.html
摘要:只要輸入的值不變,每次輸出都是一樣的值。指定位置元素運(yùn)算操作如可用以下方式代替主要是生成中最核心的對象。描述發(fā)生了什么,是響應(yīng)并對進(jìn)行更新。生成的對象包含個方法,分別為,和。按照約定,具有字段來表示它的類型。 前言: 一開始接觸redux的時候最令我記住的一句話是:You Might Not Need Redux(那我還寫這篇文章干嘛?手動滑稽) 回歸正題,本文主要是圍繞redux...
摘要:作為大型應(yīng)用狀態(tài)管理最常用的工具。它是一個應(yīng)用數(shù)據(jù)流框架,與框架類似。這是觸發(fā)變化的惟一途徑。在這個函數(shù)內(nèi)部,被調(diào)用,其作用是監(jiān)測是的。否則的話,認(rèn)為只是一個普通的,將通過也就是進(jìn)一步分發(fā)。到此源碼的主要部分學(xué)習(xí)結(jié)束。 Redux作為大型React應(yīng)用狀態(tài)管理最常用的工具。它是一個應(yīng)用數(shù)據(jù)流框架,與Flux框架類似。它是零依賴的,可以配合其他框架或者類庫一起使用。雖然在平時的工作中很多...
摘要:調(diào)用鏈中最后一個會接受真實的的方法作為參數(shù),并借此結(jié)束調(diào)用鏈。總結(jié)我們常用的一般是除了和之外的方法,那個理解明白了,對于以后出現(xiàn)的問題會有很大幫助,本文只是針對最基礎(chǔ)的進(jìn)行解析,之后有機(jī)會繼續(xù)解析對他的封裝 前言 雖然一直使用redux+react-redux,但是并沒有真正去講redux最基礎(chǔ)的部分理解透徹,我覺得理解明白redux會對react-redux有一個透徹的理解。 其實,...
摘要:另外,內(nèi)置的函數(shù)在經(jīng)過一系列校驗后,觸發(fā),之后被更改,之后依次調(diào)用監(jiān)聽,完成整個狀態(tài)樹的更新??偠灾袷剡@套規(guī)范并不是強(qiáng)制性的,但是項目一旦稍微復(fù)雜一些,這樣做的好處就可以充分彰顯出來。 這一篇是接上一篇react進(jìn)階漫談的第二篇,這一篇主要分析redux的思想和應(yīng)用,同樣參考了網(wǎng)絡(luò)上的大量資料,但代碼同樣都是自己嘗試實踐所得,在這里分享出來,僅供一起學(xué)習(xí)(上一篇地址:個人博客/s...
摘要:另外,內(nèi)置的函數(shù)在經(jīng)過一系列校驗后,觸發(fā),之后被更改,之后依次調(diào)用監(jiān)聽,完成整個狀態(tài)樹的更新??偠灾?,遵守這套規(guī)范并不是強(qiáng)制性的,但是項目一旦稍微復(fù)雜一些,這樣做的好處就可以充分彰顯出來。 這一篇是接上一篇react進(jìn)階漫談的第二篇,這一篇主要分析redux的思想和應(yīng)用,同樣參考了網(wǎng)絡(luò)上的大量資料,但代碼同樣都是自己嘗試實踐所得,在這里分享出來,僅供一起學(xué)習(xí)(上一篇地址:個人博客/s...
閱讀 3438·2023-04-25 22:04
閱讀 2217·2021-11-22 15:29
閱讀 2199·2021-10-11 10:57
閱讀 1439·2021-09-24 09:48
閱讀 3176·2021-09-09 09:34
閱讀 2579·2021-09-02 15:21
閱讀 2420·2019-08-30 15:53
閱讀 1164·2019-08-30 14:07