find()
為 Ramda 常用 Function,常搭配 propEq()
與 equals()
一併使用。
Version
macOS Catalina 10.15
VS Code 1.39.2
Quokka 1.0.258
Ramda 0.26.1
Imperative
let data = [
{ id: 1, title: 'FP in JavaScript'},
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
let find = pred => arr => {
for(let x of arr)
if (pred(x)) return x;
};
find(x => x.id === 1)(data); // ?
簡單的需求,想找到 id
為 1
的 object。
Imperative 會使用 for
loop 搭配 if
判斷,若 pred()
為 true
就 return object。
Array.prototype.reduce()
let data = [
{ id: 1, title: 'FP in JavaScript'},
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
let find = pred => arr => arr.reduce((a, x) => {
if (a !== undefined) return a;
if (pred(x)) return x;
}, undefined);
find(x => x.id === 1)(data); // ?
結果為單一 object,因此也可以使用 reduce()
完成。
因為 find()
找不到會回傳 undefined
,故 reduce()
的初始值為 undefined
。
let data = [
{ id: 1, title: 'FP in JavaScript'},
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
let find = pred => arr => arr.reduce((a, x) => (a !== undefined) ? a : (pred(x) ? x : a))
find(x => x.id === 1)(data); // ?
兩個 if
可使用 ?:
加以化簡。
let data = [
{ id: 1, title: 'FP in JavaScript'},
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
let find = pred => arr => arr.reduce((a, x) => a || (pred(x) ? x : a));
find(x => x.id === 1)(data); // ?
因為 a !=== undefind
時剛好回傳 a
自己,而 a
又是 falsy value,剛好可配合 ||
使用。
Array.prototype.find()
let data = [
{ id: 1, title: 'FP in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
let find = pred => arr => arr.find(pred);
find(x => x.id === 1)(data); // ?
ECMAScript 的 Array.prototype
有內建 find()
,可直接使用。
Ramda
import { find } from 'ramda';
let data = [
{ id: 1, title: 'FP in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
find(x => x.id === 1)(data); // ?
Ramda 也提供 find()
,可直接使用。
find()
(a → Boolean) → [a] → a | undefined
傳回第一個符合條件的資料
(a -> Boolean)
:判斷條件的 predicate
[a]
:data 為 array
a | undefined
:若找到回傳為 a
,找不到回傳 undefined
Point-free
import { find, propEq } from 'ramda';
let data = [
{ id: 1, title: 'FP in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
find(propEq('id')(1))(data); // ?
find()
的 predicate 也可使用 propEq()
加以 point-free。
Function Composition
import { find, propEq, compose } from 'ramda';
let data = [
{ id: 1, title: 'FP in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
];
let fn = compose(find, propEq('id'));
fn(1)(data); // ?
也可使用 compose()
將 find()
與 propEq()
組合成新 function。
Conclusion
find()
為 Ramda 常用 function,其 predicate 可搭配propEq()
或equals()
產生