點燈坊

失くすものさえない今が強くなるチャンスよ

使用 nonePass() 產生不符合全部條件的 Predicate

Sam Xiao's Avatar 2019-10-16

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

Version

macOS Catalina 10.15
VS Code 1.39.1
Quokka 1.0.256
ECMAScript 2015
Ramda 0.26.1
Wink-fp 0.1.12

Ramda

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

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

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() 組合。

nonepass000

Array

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

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

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

Wink-fp

import { propEq, includes, propSatisfies } from 'ramda';
import { all } from 'ramda';
import { nonePass } from 'wink-fp';

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

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

all(pred)(data); // ?

Wink-fp 已內建 nonePass(),可直接使用。

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

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

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

nonepass002

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()