點燈坊

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

使用 takeLast() 取得 String 最後幾個 Char

Sam Xiao's Avatar 2019-07-16

若只想取 String 最後幾個 Char,Ramda 提供了 takeLast()

Version

macOS Mojave 10.14.5
VS Code 1.36.1
Quokka 1.0.233
Ramda 0.26.1

Imperative

let data = 'FP in JavaScript';

// takeLast :: Number -> String -> String
let takeLast = n => str => {
  let result = '';
  let i = 0;
  let threshold = str.length - n;

  for(let elm of str) {
    if (i >= threshold) {
      result = result + elm;
    }
    i++;
  }

  return result;
};

takeLast(10)(data); // ?

建立 take(),imperative 會使用 for loop,並先建立好回傳的 result string,當 i 小於 threshold 時,elm 會塞進回 result,最後回傳 result 結束執行。

takelast000

Functional

import { drop, length } from 'ramda';

let data = 'FP in JavaScript';

// takeLast :: Number -> String -> String
let takeLast = cnt => str => drop(length(str) - cnt)(str);

takeLast(10)(data); // ?

由於只回傳最後幾個 char,相當於先用 drop() 將前幾個 char 刪除。

takelast001

import { pipe, reverse, take } from 'ramda';

let data = 'FP in JavaScript';

// takeLast :: Number -> String -> String
let takeLast = cnt => pipe(
  reverse,
  take(cnt),
  reverse
);

takeLast(10)(data); // ?

也可使用 take() 實作 takeLast()

  • 使用 reverse() 先將 string 反轉
  • 使用 take() 取得前 n 個 char
  • 使用 reverse() 將 string 反轉

最後以 pipe() 整合所有流程,非常清楚。

takelast002

Point-free

import { pipe, reverse, take, curry, useWith, identity } from 'ramda';

let data = 'FP in JavaScript';

// takeLast :: Number -> String -> String
let takeLast = curry(pipe(
  useWith(take, [identity, reverse]),
  reverse
));

takeLast(10)(data); // ?

也可以使用 useWith() 進一步 point-free。

takelast003

Ramda

import { takeLast } from 'ramda';

let data = 'FP in JavaScript';

takeLast(10)(data); // ?

Ramd 已經內建 takeLast(),可直接使用。

takeLast()
Number -> String -> String
取得 string 中最後 n 個 char

Number:前 n 個 char

string:data 為 string

[a]:回傳最後 n 個 char

takelast004

Conclusion

  • takeLast() 也可使用 drop()take() 實現
  • takeLast() 不只用在 string,也可以用於 array

Reference

Ramda, takeLast()
Ramda, drop()
Ramda, take()