Ramda 之 pickBy()

栏目: JavaScript · 发布时间: 5年前

内容简介:Ramda 之WebStorm 2018.3.3Quokka 1.0.136

Ramda 之 pick()pickAll() 都只能直接指定 Object 要擷取的 Property,若想要根據自訂條件選擇 Property,就只能靠 pickBy() ,且可再將 pickBy() 與其他 function 組合成新的 function,如此可讀性更高。

Version

WebStorm 2018.3.3

Quokka 1.0.136

Ramda 0.26.1

根據 Value 決定 Property

Non Point-free

import { map, pickBy, includes } from 'ramda';

const data = [
  { id: 1, title: 'Functional Programming in JavaScript', year: 2016 },
  { id: 2, title: 'RxJS in Action', year: 2017 },
  { id: 3, title: 'Speaking JavaScript', year: 2014 },
];

const getBooks = map(pickBy(v => includes('JavaScript', v)));
console.dir(getBooks(data));

若我們不確定要擷取 object 哪個 property,而是要根據 自訂條件 來決定,此時就要使用 pickBy() ,自行傳入 predicate function。

若需求是 object 的 value 含有 JavaScript 字眼,則擷取該 property 的 object。

pickBy()

((v, k) → boolean) → {k: v} → {k: v}

根據傳入的 predicate function,回傳新的符合條件 property 的 object

((v, k) -> boolean) :條件的 predicate function,注意其第一個參數為 value,第二個參數為 key

{k: v} :data 為 object

{k: v} :回傳符合條件 property 的 object

因為需求是 根據 value 決定 property ,因此 pickBy() 的 callback 只需第一個參數即可。

includes()

a -> [a] -> boolean

若 value 存在於 array 內時,則傳回 true ,否則傳回 false

因此將 v 傳入 includes() 第二個參數。

這種寫法是 OK 的,唯 pickBy() 的 callback 還有 v 參數,所以並不算 Point-free。

Ramda 之 pickBy()

Point-free

import { map, pickBy, includes } from 'ramda';

const data = [
  { id: 1, title: 'Functional Programming in JavaScript' },
  { id: 2, title: 'RxJS in Action' },
  { id: 3, title: 'Speaking JavaScript' },
];

const getBooks = map(pickBy(includes('JavaScript')));
console.dir(getBooks(data));

includes() 只傳進第一個參數時,將回傳 [a] -> boolean ,正好與 map() 的 callback signature 相同,因此可以使用 includes('JavaScript') 取代 v => includes('JavaScript', v) ,如此就將 v 幹掉了達成 Point-free。

import { map, pickBy, includes, compose } from 'ramda';

const data = [
  { id: 1, title: 'Functional Programming in JavaScript' },
  { id: 2, title: 'RxJS in Action' },
  { id: 3, title: 'Speaking JavaScript' },
];

const pickValueIncludes = compose(
  pickBy,
  includes,
);

const getBooks = map(pickValueIncludes('JavaScript'));
console.dir(getBooks(data));

map() 的 callback 由 pickBy(includes('JavaScript')) 構成,這種 f(g(x)) 的寫法,可讀性似乎不佳。

事實上這種 f(g(x)) 形式,正是典型的 Compose Function,最適合使用 compose() 先建立新的 function。

第 9 行

const pickValueIncludes = compose(
  pickBy,
  includes,
);

includes()pickBy() 組合成新的 pickValueIncludes() ,注意沒有任何參數,此為 Point-free。

14 行

const getBooks = map(pickValueIncludes('JavaScript'));

map() 的 callback 使用新的 pickValueIncludes() 並傳入 JavaScript ,如此寫法可讀性甚佳,可以很明確得知是從 value 判斷是否包含 JavaScript ,這就是 Function Composition 偉大之處。

Ramda 之 pickBy()

根據 Key 決定 Property

Non Point-free

import { map, pickBy, includes } from 'ramda';

const data = [
  { id: 1, title: 'Functional Programming in JavaScript' },
  { id: 2, title: 'RxJS in Action' },
  { id: 3, title: 'Speaking JavaScript' },
];

const getBooks = map(pickBy((v, k) => includes('it', k)));
console.dir(getBooks(data));

若需求是 object 的 key 含有 it 字眼,則擷取該 property 的 object。

由於 pickBy() 的 callback 中, k 是在第二個參數,因此 (v, k) 都必須使用,再將 k 傳給 includes()

同樣地這種寫法也沒有任何問題,只是 pickBy() 的 callback 包含 (v, k) ,因此不算 Point-free。

Ramda 之 pickBy()

Point-free

import { map, pickBy, includes, flip, compose } from 'ramda';

const data = [
  { id: 1, title: 'Functional Programming in JavaScript' },
  { id: 2, title: 'RxJS in Action' },
  { id: 3, title: 'Speaking JavaScript' },
];

const pickKeyIncludes = compose(
  pickBy,
  flip,
  includes,
);

const getBooks = map(pickKeyIncludes('it'));
console.dir(getBooks(data));

根據之前經驗,我們學會了組合 includes()pickBy() 成為一個新 function 當作 map() 的 callback,理論上在這裡也可如法泡製。

includes() 回傳的 signature 為 [a] -> boolean ,也就是 data 在第一個參數,但現在需求是 key,在 pickBy() 的 callback 是第二個參數,因此要使用 flip() 將第一個參數對調成第二參數的新 function,才能傳給 pickBy()

如此 map() 的 callback 就能使用新的 pickKeyIncludes('it') ,語意非常清楚,這就是 Function Composition 的魔力。

Ramda 之 pickBy()

Conclusion

  • pickBy() 讓我們可以自己傳入 predicate function,遠比 pick()pickAll() 更有彈性
  • 可將 map() 的 callback 先 compose() 成新的 function,如此可讀性更高,若 signature 不從人願,可再使用 flip() 加以轉換

Reference

Ramda , map()

Ramda , pickBy()

Ramda , includes()

Ramda , compose()

Ramda , flip()


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Nature of Code

The Nature of Code

Daniel Shiffman / The Nature of Code / 2012-12-13 / GBP 19.95

How can we capture the unpredictable evolutionary and emergent properties of nature in software? How can understanding the mathematical principles behind our physical world help us to create digital w......一起来看看 《The Nature of Code》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具