從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫

全文共2556字,預計學習時長

8分鐘

從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫

世間紛亂複雜,我們在不斷給自身做“加法”的同時,也要學會對周圍的事物做“減法”,將複雜的東西簡化,為我所用,併發揮超出原本程度的增幅效果,這才是真正的“高手”。

在“碼農圈”,學習如何使用.map()、.filter()和.reduce()函數,我們讀到、看到和聽到的一切都很複雜,無法理解這些概念,因為它們是獨立的學習單元。

聽說這些是意味著上升至啟蒙狀態的入門知識。真希望自己聽到的是實話:早點明白這三種方法其實都是識別和實現過程,循環遍歷迭代的原因通常屬於三個功能類別之一。

回顧之前編寫的代碼,筆者發現95%的情況下,在對字符串或數組進行循環時,自己都會執行以下操作之一:將語句序列映射(map)到每個值,過濾(filter)滿足特定條件的值,或者將數據集減少(reduce)到單個聚合值。

這是取得進步的關鍵時刻,Map、filter和reduce只需要執行其中的一個任務即可!

從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫

為了練習,筆者使用這些方法對舊代碼進行重構,這真是幫了大忙!

言歸正傳,繼續講解學習內容。本文將解釋每種方法,然後將常用 for循環的實現轉換為這三個各自的方法。

Map

.map()方法使用在:1.用可迭代的每個值執行一組語句;2.返回(可能)修改值。

用一個簡單的示例來計算一系列價格的營業稅:

  1. const prices = [19.99, 4.95, 25, 3.50];
  2. let new_prices = [];for(let i=0; i < prices.length; i++) {
  3. new_prices.push(prices[i] * 1.06);
  4. }

用.map()方法可以得出同樣的結果:

  1. const prices= [19.99, 4.95, 25, 3.50];let new_prices = prices.map(price => price *1.06);

上面的語法簡明扼要,所以簡單過一遍即可。

.map()函數採用回調,可以將其視為一個函數,這便是括號之間的含義。

price變量用於標識每個值的名稱,由於只有一個變量輸入,所以可以省略參數周圍的常用括號。

箭頭=>後的語句是回調的主體。由於主體只有一條語句,可以省略大括號和return關鍵字。

以防部分學習者無法理解,具體代碼如下,供詳細參考:

  1. const prices= [19.99, 4.95, 25, 3.50];let new_prices = prices.map((price) => {
  2. return price * 1.06
  3. });

Filter

當要從可迭代對象中提取值的子集時,.filter() 方法就派上了用場。使用.filter()時,請記住是在篩選值,而不是篩除值。這就意味著,迭代器中評估為true的每個項目,都將包含在過濾器中。

舉一個只保留奇數的例子:使用模運算符來計算除以2的餘數。當餘數等於1,就得知這個數是奇數。

  1. const numbers = [1,2,3,4,5,6,7,8];
  2. let odds = [];for(let i=0; i < numbers.length; i++) {
  3. if(numbers[i] % 2 == 1) {
  4. odds.push(numbers[i]);
  5. }

}與.map()類似,.filter()可以接受單個回調,以將可迭代對象中的每個值傳遞到該回調。

  1. constnumbers = [1,2,3,4,5,6,7,8];let odds = numbers.filter(num => num % 2);

此回調也適用類似的規則。由於只有一個輸入,且函數的主體是單個表達式,因此可以省略參數列表括號、定義主體的大括號和return關鍵字。

Reduce

最後,來看看.reduce()。誠然,它是三種方法中最讓人困惑的方法。從術語名稱來看,Reduce方法是指將多個值縮減為一個。然而,筆者發現,與“減少”相比,把它想成是“積累”更容易操作。

該方法通過定義起點來運行。當該方法迭代每個值時,該起點將被修改並向下傳遞。

這是將一系列數字相加的經典案例。假設正在計算某人最喜歡的慈善機構的捐款總額:

  1. constdonations = [5, 20, 100, 80, 75];
  2. let total = 0;for(let i=0; i < donations.length; i++) {
  3. total += donations[i];
  4. }

與.map()和.filter()不同,.reduce()方法的回調需要兩個參數:累加器和當前值。累加器將是第一個參數,是“向下傳遞”值。

  1. constdonations = [5, 20, 100, 80, 75];let total = donations.reduce((total,donation)=> {
  2. return total + donation;
  3. });

還可以將第二個參數傳遞給 .reduce()函數本身,作為累加器的起始值。假設加上昨天總共450美元的捐款。

  1. constdonations = [5, 20, 100, 80, 75];let total = donations.reduce((total,donation)=> {
  2. return total + donation;
  3. }, 450);

然後就能得到運行結果,這些方法並不可怕,它們能讓代碼更具可讀性!這樣就可以編寫更精簡的代碼啦,更重要的是,這實際上是在描述循環意圖!

從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫

在三個月後回顧代碼時,我們的閱讀將變得更輕鬆。不必閱讀for循環中的語句,只需理解它的高級意圖,就可以看到map/filter/reduce方法,並能開始對該塊試圖實現的目標有所想法了。

就像“哥倫布發現新大陸”一般,面對如此大的進步,我興奮不已,你呢?

從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫

從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫

我們一起分享AI學習與發展的乾貨


分享到:


相關文章: