JavaScript 陣列操作方法中的 Filter 小技巧

前言

實戰上我們時常使用 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}`); // 大於 5 的數值有:6,7,8,9,10

又或者拿來篩選字串長度大於 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}`); // I'm Array

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 將值轉換成 Boolean,判斷是否為 Falsy values(假值)並篩選出來
if (value) {
return value;
}
});

console.log(`I'm ${result.join('')}`); // I'm Is Ray Not Array

但其實你可以直接這樣寫:

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(' ')}`); // I'm Is Ray Not Array

這樣就可以直接過濾掉 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(' ')}`); // I'm Is Ray Not Array

這種寫法其實等價於以下:

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); // [ { name: 'Apple', price: 10 }, { name: 'Banana', price: 20 }, { name: 'Durian', price: 30 } ]

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); // [ { name: 'Apple', price: 10 }, { name: 'Banana', price: 20 }, { name: 'Durian', price: 30 } ]

!! 雙驚嘆號

透過 !! 雙驚嘆號將值轉換成 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); // [ { name: 'Apple', price: 10 }, { name: 'Banana', price: 20 }, { name: 'Durian', price: 30 } ]

Note
! 會將值轉換成 Boolean,!! 會將值轉換成 Boolean 後在反轉回來,過程類似 truefalse 再轉回 true

透過一些小技巧,可以讓自己的程式碼整體更乾淨,但也要注意程式碼的可讀性,不要過度簡寫,讓自己或是其他人在閱讀時會有困難哩~

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ