# 常用的 Ramda API

# unary

All for one

場合:將兩個函式組合,比如說把 A function 傳入 B function ,但此時 B function 傳入的參數跟 A function 數量不符合。

const unary = (fn) => (arg) => fn(arg);
1

範例:

['1', '2', '3'].map(parseInt); // [1, NaN, NaN]
1

unary(..) 利用了 onlyOneArg 包裝,阻擋第一參數外的參數通過,也就是例子中的 index 不會被傳進 parseInt(..) 了。

['1', '2', '3'].map(unary(parseInt)); // [1, 2, 3]
1

# identity

One on one

const identical = (v) => v;
1
const words = '   The JavaScript ecosystem is richer than ever...  '.split(
  /\s|\b/
);

console.log(words);

// ["", "", "", "The", "JavaScript", "ecosystem", "is", "richer", "than", "ever", "...", "", ""]

words.filter(identical);

// ["The", "JavaScript", "ecosystem", "is", "richer", "than", "ever", "..."]
1
2
3
4
5
6
7
8
9
10
11

# constant

有些 API 會規定只能傳入一個 function,禁止直接傳值,比如說 JS Promises 的 then(..)

const constant = (v) => () => v;
1

範例:

const fn2 = () => (...);

fn1.then(someHandlerFunc).then(constant(fn2)).then(someHandlerFunc);
1
2
3

# complement and when

  • complement:取反(取補集),回傳 反向 函式執行的結果

    const complement = (fn) => (...args) => !fn(...args);
    
    1
  • when:重構 if

    const when = (fn1, fn2) => (...args) => (fn1(...args) ? fn2(...args) : args);
    
    1

# memoizeWith

確認函式在第一次執行過後,之後再有同樣輸入值會返回快取結果,而不是重新計算。

let count = 0;
const factorial = R.memoizeWith(R.identity, (n) => {
  count++;
  let value = 1;
  for (let i = 0; i <= n; i++) {
    value = value * i;
  }
  return value;
});

factorial(5); // 120
factorial(5); // 120
factorial(5); // 120
count; // 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 綜合運用

輸入大於長度 5 的值,才做顯示。

const output = (input) => console.log(input);
const isShortEnough = (x) => x.length <= 5;

const f2 = R.partialRight(R.when, [output]);

f2(R.complement(isShortEnough))('Hello World'); // 成功輸出
1
2
3
4
5
6

找出返回的 API 值中,用戶名稱為 Scott,且未完成任務,輸出僅要四個欄位,並按照 dueDate 排序。

const postUrl =
  'https://raw.githubusercontent.com/linche0859/json-server/master/db.json';

const tryCatch = async (fn) => {
  try {
    return await fn();
  } catch (e) {
    return new Error(e);
  }
};

(async function() {
  const response = await tryCatch(() => fetch(postUrl));
  const data = await response.json();
  const getUncompleted = R.pipe(
    R.prop('tasks'),
    R.filter(R.propEq('username', 'Scott')),
    R.reject(R.propEq('complete', true)),
    R.map(R.pick(['id', 'title', 'dueDate', 'priority'])),
    R.sortBy(R.prop('dueDate'))
  );
})();

// [
//    {id: 110, title: "Rename everything", dueDate: "2013-11-15", priority: "medium"}
//    {id: 104, title: "Do something", dueDate: "2013-11-29", priority: "high"}
// ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 參考

敲敲打打玩轉 function (opens new window)

Pointfree 無點風格 (opens new window)

Referential Transparent 引用透明 (opens new window)

Last Updated: 2021/2/25 上午8:00:30