ECMAScript 對 Array 提供了 length()
讓我們獲得 Array 的大小;但對於 Object 的 Length,ECMAScript 並沒有提供直接方法,必須使用較 Tricky 方式。
Version
macOS Catalina 10.15
VS Code 1.39.2
Quokka 1.0.256
ECMAScript 2017
Ramda 0.26.1
Wink-fp 0.1.22
Object.keys()
let data = {
firstName: 'Sam',
lastName: 'Xiao'
};
let objLength = obj => Object.keys(obj).length;
objLength(data); // ?
所謂 object 的 length,其實就是 property 個數,ECMAScript 並沒有提供直接方式取得,但 array 有 length
property。
所以先使用 Object.keys()
將 key 部分變成 array,就可以使用 array.length
求得。
Object.values()
let data = {
firstName: 'Sam',
lastName: 'Xiao'
};
let objLength = obj => Object.values(obj).length;
objLength(data); // ?
既然能用 Object.keys()
,當然也能用 Object.values()
。
Object.entries()
let data = {
firstName: 'Sam',
lastName: 'Xiao'
};
let objLength = obj => Object.entries(obj).length;
objLength(data); // ?
既然 Object.keys()
與 Object.values()
都能用,當然也能使用 ES2017 的 Object.entries()
。
Pipeline
import { pipe, keys, length } from 'ramda';
let data = {
firstName: 'Sam',
lastName: 'Xiao'
};
let objLength = pipe(keys, length);
objLength(data); // ?
由以上寫法可發現資料先經過 Object.keys()
處理,再將結果傳給 Array.prototype.length
,事實上是一個 pipeline 過程,可用 pipe()
將 keys()
與 length()
整個流程串起來,也順便 point-free。
keys()
相當於 Object.keys()
的 function 版本;而 length()
相當於 Array.prototype.length
的 function 版本。
Function Composition
import { compose, keys, length } from 'ramda';
let data = {
firstName: 'Sam',
lastName: 'Xiao'
};
let objLength = compose(length, keys);
objLength(data); // ?
pipe()
是以 data 思考,若以 funciton 思考,就是將所有參與 pipeline 的 function 組合起來,也就是 function composition。
使用 compose()
將 keys()
與 length()
組合起來,也因為是組合 function,故與 argument 無關,因此自然 point-free。
Wink-fp
import { objLength } from 'wink-fp';
let data = {
firstName: 'Sam',
lastName: 'Xiao'
};
objLength(data); // ?
Wink-fp 已內建 objLength()
,可直接使用。
objLength()
[a] -> Number
取得 Object 的大小
[a]
:data 為 arrayNumber
:回傳 object 的大小,也就是 property 個數
Conclusion
- Ramda 亦提供
values()
,相當於Object.values()
,因此也能組合values()
與length()
Array.length
為 property,因此無法 function composition- OOP 與 FP 雖然功能相同,但因為提供方式不同,使用方式與觀念就相差很大
compose()
與pipe()
為一體兩面,若無法由 imperative 一步到位想到 function composition,可先由 imperative 重構成 pipeline,再由 pipeline 重構成 function composition
Reference
MDN, Object.keys()
MDN, Object.values()
MDN, Object.entries()
Ramda, keys()
Ramda, values()
Ramda, length()
Ramda, pipe()
Ramda, compose()