點燈坊

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

使用 slice() 取得部分 Array

Sam Xiao's Avatar 2020-01-29

Ramda 也如原生 ECMAScript 提供 slice(),唯 Ramda 的 slice() 是以 FP 形式呈現。

Version

macOS Mojave 10.15.2
VS Code 1.41.1
Quokka 1.0.275
Ramda 0.26.1

Imperative

let data = [1, 2, 3, 4, 5]

let slice = begin => end => arr => {
  let result = []

  for(let i = 0; i < arr.length; i++)
    if (i >= begin && i < end)
      result.push(arr[i])
  
  return result
};

slice(1)(3)(data) // ?

Imperative 會先建立欲回傳的 result array,使用 for loop 搭配 if 判斷,若 index 在傳進的 beginend 之中,則塞進 result 中。

slice008

slice()

let data = [1, 2, 3, 4, 5];

let slice = begin => end => arr => arr.slice(begin, end);

slice(1)(3)(data); // ?

ECMAScript 原生的 Array.prototype 已內建 slice(),可直接使用。

slice009

Functional

import { invoker } from 'ramda'

let data = [1, 2, 3, 4, 5]

let slice = invoker(2, 'slice')

slice(1)(3)(data) // ?

亦可使用 invoker() 調用 Array.prototypeslice()

slice004

Ramda

import { slice } from 'ramda'

let data = [1, 2, 3, 4, 5]

slice(1)(3)(data) // ?

Ramda 亦內建 slice(),可直接使用。

slice()
Number -> Number -> [a] -> [a]
回傳 array 的一部分

Number:array 的起始 index

Number:array 的結束 index (但不包含)

[a]:data 為 array

[a]:回傳新的部分 array

slice000

import { slice } from 'ramda'

let data = [1, 2, 3, 4, 5]

slice(1)(Infinity)(data) // ?

若要回傳到 array 最後一個 element,直接傳入 Infinity 即可。

Array.prototype.slice() 只要省略不傳即可,因為 ECMAScript 支援 optional parameter,預設就是最後一個 element;但 Ramda 不支援 optional parameter,而支援 partial application,因此一定要明確傳入 Infinity

slice001

import { slice } from 'ramda'

let data = [1, 2, 3, 4, 5]

slice(1)(-2)(data) // ?

Index 也可以傳入負數,其中 -1 就是最後一個 element,-2 就是倒數第二個 element,以此類推。

Array.prototype.slice() 的 index 也支援負數

slice002

import { slice } from 'ramda'

let data = [1, 2, 3, 4, 5]

slice(-3)(-1)(data) // ?

也可以兩個 argument 都是負數。

slice003

Conclusion

  • slice() 底層也是呼叫 Array.prototype.slice(),因此所有特性與原生的 slice() 相同,唯原生的 slice() 是以 OOP 設計,slice() 為 array 的 method;而 Ramda 的 slice() 是以 FP 設計,array 以參數傳入,且在最後一個參數,方便做 point-free
  • 由於 Ramda 不支援 optional parameter,而支援 partial application,因此第二個參數不能省略,若要抓到最後一個 element,要明確傳入 Infinity

Reference

Ramda, slice()