若 Function 的 argument 是很深層的 object,可以使用 ECMAScript 2015 的 Object Destructuring 加以拆解,除此之外,也可以使用 Ramda 的 path()
。
Version
macOS Mojave 10.14.5
VS Code 1.36.1
Quokka 1.0.240
Ramda 0.26.1
Non Proint-free
import { assoc, map } from 'ramda';
let data = {
data: {
books: [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
],
},
};
let addProp = (k, v) => ({ data: { books } }) => map(assoc(k, v), books);
console.dir(addProp('desc', 'Not selected')(data));
由於 ECMAScript 的 object 特性,實務上常常會遇到層數很深的 object,ES6 提供了 object destructuring,讓我們可以在 parameter list 就加以解構,非常方便。
Point-free
import { map, assoc, pipe, path } from 'ramda';
let data = {
data: {
books: [
{ id: 1, title: 'Functional Programming in JavaScript' },
{ id: 2, title: 'RxJS in Action' },
{ id: 3, title: 'Speaking JavaScript' },
],
},
};
let addProp = (k, v) => pipe(
path(['data', 'books']),
map(assoc(k, v)),
);
console.dir(addProp('desc', 'not selected')(data));
(k, v)
由於是條件部分,無法省略,但 ({ data: { books } })
屬 data 部分,是否有機會 point-free 呢 ?
path()
[Idx] → {a} → a | Undefined
將層數很深的 object 加以解構
[Idx]
:array,描述要解構的 property
{a}
:要解構的 object
a | Undefined
:若能解構則回傳 a
,若無法解構成回傳 undefined
13 行
let addProp = (k, v) => pipe(
path(['data', 'books']),
map(assoc(k, v)),
);
將 ({ data: { books } })
省略,直接由 pipe()
傳給 path()
第二個參數,而 path()
第一個參數則以 array 形式描述要拆解的 property,如同 object destructuring 一樣。
path()
解構之後,再將 array 傳給 map()
的第二個參數。
如此 addProp()
就 Point-free 了。
Conclusion
- 參數為 object 時,固然可以使用 object destructuring 加以解構,但也可使用 Ramda 的
path()
,可讀性更好,還可以 point-free