將眾多 Predicate 組合成單一 Predicate,只要任何 Predicate 成立即可

Ramda 有 any() 並不令人訝異,ECMAScript 也有 some(),但 Ramda 又另外提供了 anyPass(),這與 any() 有什麼不同呢 ?

Version


VS Code 1.33.0
Quokka 1.0.205
Ramda 0.26.1

anyPass()


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

let data = { title: 'FP in JavaScript', price: 100 };

let isGoodPrice = anyPass([
propEq('price', 100),
propEq('price', 200)
]);

console.log(isGoodPrice(data));

若只要 price100200,我們都認為是合理的價錢。

以 FP 的角度,我們必須提供兩個 predicate,但只要其中一個 predicate 成立即可,因此使用 Ramda 的 anyPass() 將兩個使用 propEq() 產生的 predicate 組合成單一 predicate。

注意新 predicate 接受的 data 與原本 predicate 都相同,一樣是 object。

anyPass()
[(*… → Boolean)] → (*… → Boolean)
將眾多 predicate 組合成單一 predicate,只要任何 predicate 成立即可

[(*… → Boolean)]:眾多 predicate 組合在 array 中

(*… → Boolean):組合成單一 predicate

anypass000

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { anyPass, propEq, any } from 'ramda';

let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
];

let isGoodPrice = anyPass([
propEq('price', 100),
propEq('price', 200)
]);

console.log(any(isGoodPrice)(data));

Q:any()anyPass() 的差別在哪 ?

any() 接受的是單一 predicate,data 為 array,結果為 boolean。

anyPass() 接受的是多個 predicate,data 為 object,結果還是 predicate。

因此若要 array 能接受多個 predicate,就必須組合 any()anyPass()

anypass001

Conclusion


  • any() 的結果是 boolean;而 anyPass() 的結果是 predicate
  • anyPass()any() 的昇華:any() 的對象是 array,只能使用單一 predicate;而 anyPass() 的對象是 object,能使用多個 predicate
  • 若要 array 適用於多個 predicate,就必須組合 any()anyPass()

Reference


Ramda, any()
Ramda, anyPass()