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


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

查看所有标签

猜你喜欢:

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

代码之外的功夫

代码之外的功夫

[美] Gregory T. Brown / 李志 / 人民邮电出版社 / 2018-3-1 / 49.00元

本书虽然面向程序员,却不包含代码。在作者看来,90%的程序设计工作都不需要写代码;程序员不只是编程专家,其核心竞争力是利用代码这一工具解决人类社会的常见问题。以此作为出发点,作者精心构思了8个故事,以情景代入的方式邀请读者思考代码之外的关键问题:软件开发工作如何从以技术为中心转为以人为本?透过故事主人公的视角,读者能比较自己与书中角色的差异,发现决策过程的瑕疵,提升解决问题的综合能力。 书中......一起来看看 《代码之外的功夫》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具