點燈坊

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

如何將 Array 傳進 Function ?

Sam Xiao's Avatar 2019-08-15

若 Function 有 n 個 Argument,但實際 Data 卻為 n 個 Element 的 Array,當然可將 Array 一一拆解傳進 Function,但有更精簡寫法。

Version

macOS Mojave 10.14.5
VS Code 1.35.1
Quokka 1.0.232
ECMAScript 2015
Ramda 0.26.1

Function

let data = [1, 2, 3];

let fn = (x, y, z) => x + y + z;

fn(data[0], data[1], data[2]); // ?

fn() 為 3 個 argument 的 function,但 data 卻是 3 個 element 的 array。

當然可用 index 寫法將 element 取出傳進 function。

pass000

Function.prototype.apply()

let data = [1, 2, 3];

let fn = (x, y, z) => x + y + z;

fn.apply(null, data); // ?

ES5 提供了 Function.prototype.apply() ,因此每個 function 都可使用自帶的 apply() 傳入 array。

apply() 的第一個 argument 為傳入 object 取代 this,因為 fn() 沒使用到 this,因此傳入 null 即可。

pass001

Spread Operator

let data = [1, 2, 3];

let fn = (x, y, z) => x + y + z;

fn(...data); // ?

ES6 迎來了 ... spread operator,可將 array element 展開之後,再傳入 fn()

pass002

Ramda

import { apply } from 'ramda';

let data = [1, 2, 3];

let fn = (x, y, z) => x + y + z;

apply(fn, data); // ?

Ramda 也提供了 apply(),為 Array.prototype.apply() 的 FP 版本。

apply()
(*… → a) → [*] → a
將 argument function 變成以 array 為輸入的單一 argument function

(*… → a):原本多 argument function

[*] -> a:回傳以 array 為單一 argument function

pass003

Conclusion

  • 若以原生寫法,... spread operator 最精簡,且可讀性最高
  • Ramda 的 apply() 適合 function composition 與 point-free

Reference

MDN, Function.prototype.apply()
MDN, Spread syntax
Ramda, apply()