點燈坊

學而時習之,不亦悅乎

自行組合 objLength() 取得 Object 的 Length

Sam Xiao's Avatar 2019-09-04

ECMAScript 對 Array 提供了 length() 讓我們獲得 Array 的大小;但對於 Object 的 Length,ECMAScript 並沒有提供直接方法,必須使用較 Tricky 方式。

Version

macOS Mojave 10.14.6
VS Code 1.37.1
Quokka 1.0.240
ECMAScript 2017
Ramda 0.26.1

ECMAScript

let data = {
  firstName: 'Sam',
  lastName: 'Xiao'
};

let objLength = obj => Object.keys(obj).length;

objLength(data); // ?

所謂 object 的 length,其實就是指 property 個數,ECMAScript 並沒有提供直接的方式取得,但 array 有 length

所以先使用 Object.keys() 將 key 部分變成 array,就可以使用 array.length 求得。

objsize000

let data = {
  firstName: 'Sam',
  lastName: 'Xiao'
};

let objLength = obj => Object.values(obj).length;

objLength(data); // ?

既然能用 Object.keys(),當然也能用 Object.values()

objsize001

let data = {
  firstName: 'Sam',
  lastName: 'Xiao'
};

let objLength = obj => Object.entries(obj).length;

objLength(data); // ?

既然 Object.keys()Object.values() 都能用,當然也能使用 ES2017 的 Object.entries()

objsize002

Ramda

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 版本。

objsize004

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。

objsize003

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()