内容简介:一直很羨慕 F# 的但這一切終於得到解決,Ramda 擁有豐富的 Operator,且很容易自行開發 Operator 與 Ramda 整合使用。Ramda 0.26.1
一直很羨慕 F# 的 List
module 提供了豐富的 Operator,而 ECMAScript 的 Array.prototype
卻只提供有限的 Operator 可用,因此無法完全發揮 FP 威力。
但這一切終於得到解決,Ramda 擁有豐富的 Operator,且很容易自行開發 Operator 與 Ramda 整合使用。
Version
Ramda 0.26.1
Imperative
const books = [ {year: 2016, title: 'functional Programming in JavaScript'}, {year: 2017, title: 'rxJS in Action'}, {year: 2014, title: 'speaking JavaScript'}, ]; const titlesForYear = (year, data) => { const result = []; for(let i = 0; i < data.length; i++) { if (data[i].year === year) { result.push(data[i].title); } } return result; }; const result = titlesForYear(2016, books); console.log(result);
很簡單的需求, books
array 有各書籍資料,包含 year
與 title
,我們想得到 2016
年份的書籍資料,且只要 書名
即可。
若使用 Imperative 寫法,我們會使用 for
loop,先建立要回傳的 result
array,由 if
去判斷 2016
年,再將符合條件的 書名
寫入 result
array,最後再回傳。
Array.Prototype
const books = [ {year: 2016, title: 'functional Programming in JavaScript'}, {year: 2017, title: 'rxJS in Action'}, {year: 2014, title: 'speaking JavaScript'}, ]; const titlesForYear = (data, year) => data .filter(x => x.year === year) .map(x => x.title); const result = titlesForYear(books, 2016); console.log(result);
熟悉 FP 的讀者會很敏感發現,這就是典型 filter()
與 map()
而已,我們可直接使用 ECMAScript 在 Array.prototype
內建的 filter()
與 map()
即可完成需求。
Ramda
import { filter, map, pipe } from 'ramda'; const books = [ {year: 2016, title: 'functional Programming in JavaScript'}, {year: 2017, title: 'rxJS in Action'}, {year: 2014, title: 'speaking JavaScript'}, ]; const forYear = year => x => x.year === year; const onlyTitle = x => x.title; const titlesForYear = (year, data) => pipe( filter(forYear(year)), map(onlyTitle), )(data); const result = titlesForYear(2016, books); console.log(result);
Ramda 身為 Functional Library,內建 filter()
與 map()
operator 自然不在話下。
我們可先用 pipe()
將 filter()
與 map()
組合
出新的 function,再將 data
傳入。
至於 filter()
與 map()
要傳入的 callback,當然也可以直接使用 Arrow Function,不過在 Ramda 會習慣將 callback 也建立 function,如此可讀性較高。
import { filter, map, compose } from 'ramda'; const books = [ {year: 2016, title: 'functional Programming in JavaScript'}, {year: 2017, title: 'rxJS in Action'}, {year: 2014, title: 'speaking JavaScript'}, ]; const forYear = year => x => x.year === year; const onlyTitle = x => x.title; const titlesForYear = (year, data) => compose( map(onlyTitle), filter(forYear(year)), )(data); const result = titlesForYear(2016, books); console.log(result);
pipe()
是 由左向右
,當然你也可以使用 compose()
為 由右向左
。
至於該用 pipe()
或 compose()
都可以,但本質都是 組合
function,看哪種寫法你的思考較順。
Ramda 風格有個特色:會 組合
小 function
成為 大 function
,所以在 Ramda 幾乎看不到 {}
,最後一個 function 會使用 pipe()
或 compose()
將 小 function
組合起來
User Operator
import { filter, map, pipe } from 'ramda'; const books = [ {year: 2016, title: 'functional Programming in JavaScript'}, {year: 2017, title: 'rxJS in Action'}, {year: 2014, title: 'speaking JavaScript'}, ]; const forYear = year => x => x.year === year; const onlyTitle = x => x.title; const capitalize = data => map(x => x[0].toUpperCase() + x.slice(1), data); const titlesForYear = (data, year) => pipe( filter(forYear(year)), map(onlyTitle), capitalize, )(data); const result = titlesForYear(books, 2016); console.log(result);
眼尖的讀者會發現結果的 functional Programming in JavaScript
的 f
為小寫,原始的資料就是如此,但 F
為大寫較符合英文閱讀習慣。
因此我們可以自行寫一個 capitalize()
operator,將第一個字母變成大寫。
在 Ramda 要成為能夠 pipe()
或 compose()
的 operator 條件很簡單,只要 function 是單一 parameter 即可,且是 Pure Function。
Conclusion
- Ramda 提供了 FP 該有的 operator,不再侷限於
Array.prototype
有限的 operator - Ramda 可以很容易的擴充 operator,不再擔心污染
Array.prototype
- Ramda 使用
pipe()
與compose()
,觀念上更接近 FP 的 Compose Function
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Spring揭秘
王福强 / 人民邮电出版社 / 2009.8 / 99.00元
没有教程似的训导,更多的是说故事般的娓娓道来,本书是作者在多年的工作中积累的第一手Spring框架使用经验的总结,深入剖析了Spring框架各个模块的功能、出现的背景、设计理念和设计原理,揭开了Spring框架的神秘面纱,使你“知其然,更知其所以然”。每部分的扩展篇帮助读者活学活用Spring框架的方方面面,同时可以触类旁通,衍生出新的思路和解决方案。 本书内容全面,论述深刻入理,必将成为每......一起来看看 《Spring揭秘》 这本书的介绍吧!