點燈坊

學而時習之,不亦悅乎

自行組合 nonePass() 產生不符合全部條件的 Predicate

Sam Xiao's Avatar 2019-07-07

Ramda 有提供 anyPass()allPass(),卻沒有提供 nonePass(),沒關係,藉由 Function Composition,我們也可以自行組合出 nonePass()

Version

macOS Mojave 10.14.5
VS Code 1.33.0
Quokka 1.0.205
Ramda 0.26.1

Ramda

import { anyPass, propEq, compose, complement, includes, propSatisfies } from 'ramda';

let data = { title: 'Rx in Action', price: 200 };

// nonePass :: [(*… → Boolean)] → (*… → Boolean)
let nonePass = compose(
  complement,
  anyPass
);

let pred = nonePass([
  propEq('price', 400),
  propSatisfies(includes('JavaScript'), 'title')
]);

pred(data); // ?

若不存在 price400 ,也不包含 titleJavaScript,則傳回 true,否則傳回 false

none() 可藉由complement()any() 組合出來,同理,nonePass() 也可藉由 complement()anyPass() 組合出來

nonePass()
[(*… → Boolean)] → (*… → Boolean)
將眾多 predicate 組合成單一 predicate,必須沒有任何 predicate 成立

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

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

nonepass000

Array

import { anyPass, propEq, compose, complement, includes, propSatisfies, all } from 'ramda';

let data = [
  { title: 'Exloring ES6', price: 100 },
  { title: 'RxJS in Action', price: 200 },
  { title: 'Exploring ReasonML', price: 300 }
];

// nonePass :: [(*… → Boolean)] → (*… → Boolean)
let nonePass = compose(
  complement,
  anyPass
);

let pred = nonePass([
  propEq('price', 400),
  propSatisfies(includes('JavaScript'), 'title')
]);

all(pred)(data); // ?

若 array 所有 object 都不符合條件則傳回 true,否則傳回 false

使用 all()nonePass() 組合,則可針對 array 做判斷。

nonepass001

Conclusion

  • 因為較少使用,Ramda 並有提供 nonePass(),但藉由 Function Composition,我們仍可使用 complement()anyPass() 組合出 nonePass()
  • nonePass() 要配合 array 時比較 tricky,並不是 none() 而是 all(),因為 nonePass() 已經做過一次 反向邏輯,再使用 none() 會變成 負負得正 效果,因此只能用 all()

Reference

Ramda, compose()
Ramda, complement()
Ramda, anyPass()
Ramda, propEq()
Ramda, propSatisfies()
Ramda, includes()
Ramda, all()