- 原文地址:An Illustrated (and Musical) Guide to Map, Reduce, and Filter Array Methods
- 原文做者:Una Kravets
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:熊賢仁
- 校對者:Endone、Reaper622
map、reduce 和 filter 是三個很是實用的 JavaScript 數組方法,賦予了開發者四兩撥千斤的能力。咱們直接進入正題,看看如何使用(並記住)這些超級好用的方法!css
Array.map()
根據傳遞的轉換函數,更新給定數組中的每一個值,並返回一個相同長度的新數組。它接受一個回調函數做爲參數,用以執行轉換過程。前端
let newArray = oldArray.map((value, index, array) => {
...
});
複製代碼
一個幫助記住 map 的方法:Morph Array Piece-by-Piece(逐個改變數組)android
你能夠使用 map 代替 for-each 循環,來遍歷並對每一個值應用轉換函數。這個方法適用於當你想更新數組的同時保留原始值。它不會潛在地刪除任何值(filter 方法會),也不會計算出一個新的輸出(就像 reduce 那樣)。map 容許你逐個改變數組。一塊兒來看一個例子:ios
[1, 4, 6, 14, 32, 78].map(val => val * 10)
// the result is: [10, 40, 60, 140, 320, 780]
複製代碼
上面的例子中,咱們使用一個初始數組([1, 4, 6, 14, 32, 78]
),映射每一個值到它本身的十倍(val * 10
)。結果是一個新數組,初始數組的每一個值被這個等式轉換:[10, 40, 60, 140, 320, 780]
。git
當咱們想要過濾數組的值到另外一個數組,新數組中的每一個值都經過一個特定檢查,Array.filter()
這個快捷實用的方法就派上用場了。github
相似搜索過濾器,filter 基於傳遞的參數來過濾出值。後端
舉個例子,假定有個數字數組,想要過濾出大於 10 的值,能夠這樣寫:數組
[1, 4, 6, 14, 32, 78].filter(val => val > 10)
// the result is: [14, 32, 78]
複製代碼
若是在這個數組上使用 map 方法,好比在上面這個例子,會返回一個帶有 val > 10
判斷的和原始數組長度相同的數組,其中每一個值都通過轉換或者檢查。若是原始值大於 10,會被轉換爲真值。就像這樣:ide
[1, 4, 6, 14, 32, 78].map(val => val > 10)
// the result is: [false, false, false, true, true, true]
複製代碼
可是 filter 方法,只返回真值。所以若是全部值都執行指定的檢查的話,結果的長度會小於等於原始數組。函數
把 filter 想象成一個漏斗。部分混合物會從中穿過進入結果,而另外一部分則會被留下並拋棄。
假設寵物訓練學校有一個四隻狗的小班,學校裏的全部狗都會通過各類挑戰,而後參加一個分級期末考試。咱們用一個對象數組來表示這些狗狗:
const students = [
{
name: "Boops",
finalGrade: 80
},
{
name: "Kitten",
finalGrade: 45
},
{
name: "Taco",
finalGrade: 100
},
{
name: "Lucy",
finalGrade: 60
}
]
複製代碼
若是狗狗們的期末考試成績高於 70 分,它們會得到一個精美的證書;反之,它們就要去重修。爲了知道證書打印的數量,要寫一個方法來返回經過考試的狗狗。沒必要寫循環來遍歷數組的每一個對象,咱們能夠用 filter
簡化代碼!
const passingDogs = students.filter((student) => {
return student.finalGrade >= 70
})
/* passingDogs = [ { name: "Boops", finalGrade: 80 }, { name: "Taco", finalGrade: 100 } ] */
複製代碼
你也看到了,Boops 和 Taco 是好狗狗(其實全部狗都很不錯),它們取得了經過課程的成就證書!利用箭頭函數的隱式返回特性,一行代碼就能實現。由於只有一個參數,因此能夠刪掉箭頭函數的括號:
const passingDogs = students.filter(student => student.finalGrade >= 70)
/* passingDogs = [ { name: "Boops", finalGrade: 80 }, { name: "Taco", finalGrade: 100 } ] */
複製代碼
reduce()
方法接受一個數組做爲輸入值並返回一個值。這點挺有趣的。reduce 接受一個回調函數,回調函數參數包括一個累計器(數組每一段的累加值,它會像雪球同樣增加),當前值,和索引。reduce 也接受一個初始值做爲第二個參數:
let finalVal = oldArray.reduce((accumulator, currentValue, currentIndex, array) => {
...
}), initalValue;
複製代碼
來寫一個炒菜函數和一個做料清單:
// our list of ingredients in an array
const ingredients = ['wine', 'tomato', 'onion', 'mushroom']
// a cooking function
const cook = (ingredient) => {
return `cooked ${ingredient}`
}
複製代碼
若是咱們想要把這些做料作成一個調味汁(開玩笑的),用 reduce()
來歸約!
const wineReduction = ingredients.reduce((sauce, item) => {
return sauce += cook(item) + ', '
}, '')
// wineReduction = "cooked wine, cooked tomato, cooked onion, cooked mushroom, "
複製代碼
初始值(這個例子中的 ''
)很重要,它決定了第一個做料可以進行烹飪。這裏輸出的結果不太靠譜,本身炒菜時要小心。下面的例子就是我要說到的狀況:
const wineReduction = ingredients.reduce((sauce, item) => {
return sauce += cook(item) + ', '
})
// wineReduction = "winecooked tomato, cooked onion, cooked mushroom, "
複製代碼
最後,確保新字符串的末尾沒有額外的空白,咱們能夠傳遞索引和數組來執行轉換:
const wineReduction = ingredients.reduce((sauce, item, index, array) => {
sauce += cook(item)
if (index < array.length - 1) {
sauce += ', '
}
return sauce
}, '')
// wineReduction = "cooked wine, cooked tomato, cooked onion, cooked mushroom"
複製代碼
能夠用三目操做符、模板字符串和隱式返回,寫的更簡潔(一行搞定!):
const wineReduction = ingredients.reduce((sauce, item, index, array) => {
return (index < array.length - 1) ? sauce += `${cook(item)}, ` : sauce += `${cook(item)}`
}, '')
// wineReduction = "cooked wine, cooked tomato, cooked onion, cooked mushroom"
複製代碼
記住這個方法的簡單辦法就是回想你怎麼作調味汁:把多個做料歸約到單個。
我想要用一首歌來結束這篇博文,給數組方法寫了一個小調,來幫助大家記憶:
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。