takeLast()
只能取得 String 固定最後幾個 Char,若想自行提供自訂條件 Predicate,就得使用 takeLastWhile()
。
Version
macOS Mojave 10.14.5
VS Code 1.36.1
Quokka 1.0.235
Ramda 0.26.1
Imperative
let data = 'FP in JavaScript';
// takeLastWhile :: (a → Boolean) → String → String
let takeLastWhile = pred => str => {
let result = '';
for(let i = str.length - 1; i >= 0; i--) {
if (pred(str[i]))
result = str[i] + result;
else
break;
}
return result;
};
takeLastWhile(x => x !== ' ')(data); // ?
takeLastWhile()
意義為當 predicate 為 true
時從最後取得 char,直到 false
時停止取得。
建立 takeLastWhile()
,imperative 會先建立回傳 result
string,i
從最後 index 開始,當 predicate 成立時,從 result
前面塞進 char,不成立馬上離開 for
loop,最後回傳 result
。
Functional
import { pipe, reverse, takeWhile } from 'ramda';
let data = 'FP in JavaScript';
// takeLastWhile :: (a → Boolean) → String → String
let takeLastWhile = pred => pipe(
reverse,
takeWhile(pred),
reverse
);
takeLastWhile(x => x !== ' ')(data); // ?
若一開始不知道 takeLastWhile()
也沒關係,可藉由已知的 takeWhile()
加以組合:
- 使用
reverse()
將 string 反轉 - 使用
takeWhile()
根據 predicate 條件取得 char - 使用
reverse()
再將 string 反轉
最後使用 pipe()
組合所有 function,非常清楚。
Point-free
import { pipe, reverse, takeWhile, useWith, identity } from 'ramda';
let data = 'FP in JavaScript';
// takeLastWhile :: (a → Boolean) → String → String
let takeLastWhile = useWith(
pipe(takeWhile, reverse), [
identity,
reverse
]
);
takeLastWhile(x => x !== ' ')(data); // ?
也可以使用 useWith()
進一步將 pred
point-free,由 pipe()
寫法可發現:
reverse()
看似最後執行,但實則pipe(takeWhile, reverse)
才是最後執行 function- 第一個 argument 為 predicate,因為不變,所以為
identity()
- 第二個 argument 為
reverse()
由於第一個 argument 與第二個 argument 並不相關,明顯暗示需使用 useWith()
才能 point-free。
Ramda
import { takeLastWhile } from 'ramda';
let data = 'FP in JavaScript';
takeLastWhile(x => x !== ' ')(data); // ?
Ramda 已經提供 takeLastWhile()
,可直接使用。
takeLastWhile()
(a → Boolean) → [a] → [a]
根據自訂條件取得 string 最後幾個 char
(a -> Boolean)
:自訂條件 predicate
[a]
:data 為 string
[a]
:回傳 string 最後幾個 char
Point-free
import { takeLastWhile, equals, complement } from 'ramda';
let data = 'FP in JavaScript';
let pred = complement(equals(' '));
takeLastWhile(pred)(data); // ?
也可將 x => x !== ' '
進一步 point-free。
- 使用
equals()
判斷相等,相當於=== ' '
- 使用
complement()
使其結果反向,相當於!
Conclusion
takeLastWhle()
與takeWhile()
用法很類似,但takeWhile()
是取得前幾個 char,而takeLastWhile()
是取得最後幾個 chartakeLastWhile()
除了用在 string,也能用在 array