前言
實戰上我們時常使用 JavaScript 陣列操作方法 Filter 來過濾篩選陣列中的特定元素,例如:這個陣列中只要數值大於 10 的就會被篩選出來,所以實戰上可以說是非常常用的方法。
Array.prototype.filter()
前面有提到 filter 可以依照我們所需要的條件來過濾陣列中的元素,這邊就來看看 filter 的基本用法:
1 2 3 4 5
| const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const result = numbers.filter((number) => number > 5);
console.log(`大於 5 的數值有:${result}`);
|
又或者拿來篩選字串長度大於 3 的元素:
1 2 3 4 5
| const data = ['Is', 'Ray', 'Not', 'Array'];
const result = data.filter((str) => str.length > 3);
console.log(`I'm ${result}`);
|
Note
Template literals(樣板字面值) 如果傳入陣列時,會因為 Array.prototype.toString() 的關係而將陣列轉為字串,所以才會沒有出現 I'm ['Array'] 的狀況。
Filter 小技巧
首先我們在開發上可能會需要將陣列中某些值給過濾掉,例如…
- 空字串(
'' or "")
null(空值)
undefined(未定義)
0(數字零)
false(布林值)
NaN (Not a Number,不是一個數字)
這些我們稱之為 Falsy values(假值),通常來講,我們在過濾這些值時,可能會這樣寫:
1 2 3 4 5 6 7 8 9 10
| const data = ['Is', '', 'Ray', 'Not', null, 'Array', undefined, 0, false, NaN];
const result = data.filter((value) => { if (value) { return value; } });
console.log(`I'm ${result.join('')}`);
|
但其實你可以直接這樣寫:
1 2 3 4 5
| const data = ['Is', '', 'Ray', 'Not', null, 'Array', undefined, 0, false, NaN];
const result = data.filter((str) => str);
console.log(`I'm ${result.join(' ')}`);
|
這樣就可以直接過濾掉 Falsy values(假值),那為什麼沒有寫 if 判斷卻可以直接這樣寫呢?這是因為 filter 會自動過濾掉 false 的值,所以我們才可以直接忽略 if 判斷。
Note
請注意不要將 data.filter((str) => str); 改成 data.filter(str);,這樣會導致 filter 無法正確運作。
那麼只有這種寫法嗎?不能忽略 (str) => str 嗎?我們不能再更簡寫一點嗎?答案是可以的,但是我們要搭配 Boolean 這個方法,只要將 (str) => str 改成 Boolean 就可以了:
1 2 3 4 5
| const data = ['Is', '', 'Ray', 'Not', null, 'Array', undefined, 0, false, NaN];
const result = data.filter(Boolean);
console.log(`I'm ${result.join(' ')}`);
|
這種寫法其實等價於以下:
1 2 3 4 5
| const data = ['Is', '', 'Ray', 'Not', null, 'Array', undefined, 0, false, NaN];
const result = data.filter((str) => { return Boolean(str); });
|
在 MDN 中有說明 Boolean 只要傳入的值是 Falsy values(假值)就會回傳 false,反之則回傳 true,透過這個方式就可以快速過濾掉 Falsy values(假值)囉~
但是我們實戰上的情境肯定不可能是這們單純的陣列,通常會是陣列+物件的格式,那麼如果要達到一樣效果過濾掉 Falsy values(假值)呢?接下來就讓我們來看一下吧
物件解構
透過物件解構方式,先將 price 從物件中解構出來,直接利用 filter 特性直接過濾掉 Falsy values(假值):
1 2 3 4 5 6 7 8 9 10 11
| const products = [ { name: 'Apple', price: 10 }, { name: 'Banana', price: 20 }, { name: 'Cherry', price: 0 }, { name: 'Durian', price: 30 }, { name: 'Elderberry', price: 0 }, ];
const result = products.filter(({ price }) => price);
console.log(result);
|
Boolean 方法
透過 Boolean 方法來過濾掉 Falsy values(假值):
1 2 3 4 5 6 7 8 9 10 11
| const products = [ { name: 'Apple', price: 10 }, { name: 'Banana', price: 20 }, { name: 'Cherry', price: 0 }, { name: 'Durian', price: 30 }, { name: 'Elderberry', price: 0 }, ];
const result = products.filter(({ price }) => Boolean(price));
console.log(result);
|
!! 雙驚嘆號
透過 !! 雙驚嘆號將值轉換成 Boolean,過濾掉 Falsy values(假值):
1 2 3 4 5 6 7 8 9 10 11
| const products = [ { name: 'Apple', price: 10 }, { name: 'Banana', price: 20 }, { name: 'Cherry', price: 0 }, { name: 'Durian', price: 30 }, { name: 'Elderberry', price: 0 }, ];
const result = products.filter(({ price }) => !!price);
console.log(result);
|
Note
! 會將值轉換成 Boolean,!! 會將值轉換成 Boolean 後在反轉回來,過程類似 true 轉 false 再轉回 true。
透過一些小技巧,可以讓自己的程式碼整體更乾淨,但也要注意程式碼的可讀性,不要過度簡寫,讓自己或是其他人在閱讀時會有困難哩~