將符合條件的資料去除,並回傳新的 array

filter() 是 FP 代表性的 operator,但若想表達的是 請將符合條件的資料不顯示,當然也可以繼續使用 filter() 搭配 反向邏輯,語義則變成 請將不符合條件資料顯示;Ramda 特別提供了 reject(),讓我們能夠使用 正向邏輯 表示。

Version


VS Code 1.31.1
Quokka 1.0.136
Ramda 0.26.1

filter()


1
2
3
4
5
6
7
8
9
10
import { filter } from 'ramda';

const data = [
{ id: 1, title: 'FP in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' }
];

const getBooks = filter(x => x.title !== 'RxJS in Action');
console.dir(getBooks(data));

若我們想找出所有 title 不是 RxJS in Action 的書,若使用 filter(),勢必使用 反向邏輯,也就是 !==

filter()
(a -> Boolean) -> [a] -> [a]
回傳符合條件的 array

reject000

Point-free


1
2
3
4
5
6
7
8
9
10
11
12
13
import { filter, propEq, compose, not } from 'ramda';

const data = [
{ id: 1, title: 'FP in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' }
];

const getBooks = filter(compose(
not,
propEq('title', 'RxJS in Action')
));
console.dir(getBooks(data));

若要求 predicate function 為 Point-free,則必須使用 compose()propEq()not() 組合起來。

reject001

reject()


1
2
3
4
5
6
7
8
9
10
import { reject, propEq } from 'ramda';

const data = [
{ id: 1, title: 'FP in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' }
];

const getBooks = reject(propEq('title', 'RxJS in Action'));
console.dir(getBooks(data));

reject()filter() 的 complement function,因此 predicate 直接提供 正向邏輯 即可。

reject()
(a → Boolean) → [a] → [a]
將符合條件的資料去除,並回傳新的 array

(a -> Boolean):Predicate function,指定去除的條件

[a]:data 為 array

[a]:回傳去除資料後的新 array

reject002

Conclusion


  • 寫程式盡量避免 反向邏輯,因為人類頭腦較能思考 正向邏輯
  • 當 predicate function 為 反向邏輯 時,建議使用 reject() 取代 filter()

Reference


Ramda, filter()
Ramda, reject()