函数式编程五:lodash中的fp模块,PointFree的理解

在使用函数组合解决问题的时候,会使用到lodash中提供的一些方法,但是这些方法有多个参数的时候,需要对这些方法进行柯里化的处理,需要重新包装这些方法稍微有些麻烦, lodash中fp模块,提供了一些实用的对函数式编程友好的方法。提供的方法是不可变的,如果一个方法的参数是函数的话,会要求函数优先并且数据置后。

lodash模块的方法和lodash/fp模块方法的区别

//lodash 模块
const _ = require("lodash");

_.map(["a", "b", "c"], _.toUpper);
//=>['A','B','C']
_.map(["a", "b", "c"]);
//=>['a','b','c']

_.split("Hello World", " ");

lodash模块中的map方法和split方法,map方法可以对数组进行遍历,并且在遍历的过程中可以指定一个函数对数组中的每个元素进行处理,在调用的时候要求数据优先,函数置后,当map方法只传递了一个参数,没有传递这个函数的时候,会原封不动的返回这个数组。
split方法是对字符串进行切割,会要求首先传递数据,再传入分割符。传入的参数都是数据优先,函数置后的。

//lodash/fp模块
const fp = require("lodash/fp");
fp.map(fp.toUpper, ["a", "b", "c"]);
fp.map(fp.toUpper)(["a", "b", "c"]);

fp.split(" ", "Hello World");
fp.split(" ")("Hello World");

再看lodash/fp中提供的这些方法。和上面是相反的,先传入函数再传入数据,如果只传入了一个参数,此时会返回一个新的函数,来等待接收剩余的参数,所以map是一个柯里化的函数,split也是传入一个分割符,返回一个函数等待接收剩余的参数

//NEVER SAY DIE 转 never-say-die
const _ = require("lodash");

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, array) => _.join(array, sep));
const map = _.curry((fn, array) => _.map(array, fn));
const f = _.flowRight(join("-"), map(_.toLower), split(" "));

console.log(f("NEVER SAY DIE"));

看之前这个例子,这个例子是我上一篇文章里用来演示函数组合如何调试的例子。
我们之前在使用lodash中的方法,来组合成新的函数的时候,需要对split,join,map来进行重新包装,因为这些方法都是数据优先,函数置后,而且没有被柯里化,所以在使用的时候都调了curry函数。
通过fp模块来改造一下代码

const fp = require("lodash/fp");
const f = fp.flowRight(fp.join("-"), fp.map(fp.toLower), fp.split(" "));
console.log(f("NEVER SAY DIE"));

运行结果是一样的。
在这里插入图片描述
在lodash和lodash/fp模块中map方法有哪些区别呢?

const _ = require("lodash");
console.log(_.map(["23.3", "8", "10"], parseInt));

打印的结果却是
在这里插入图片描述
再看一下lodash/fp中的map

const fp = require("lodash/fp");
console.log(fp.map(parseInt, ["23.3", "8", "10"]));

打印结果才是转成 int后的结果
在这里插入图片描述
这两个区别是parseInt接收的参数不一样,lodash中所接收的参数是3个,第一个是要处理的每个元素,第二个是索引(而parseInt第二个参数是转成几进制数),第三个是数组,而lodash/fp中这个map方法他所接收的parseInt函数的参数,只有一个当前处理的元素。

最后再来说说PointFree。
PointFree是一个编程的风格,他的具体实现就是函数的组合,只是感觉更抽象一些
PointFree:我们可以把数据处理的过程定义成与数据无关的合成运算,不需要用到代表数据的那个参数,只要把简单的运算步骤合成到一起,在使用这种模式之前我们需要定义一些辅助的基本运算函数。

  • 不需要指明处理的数据
    - 只需要合成运算过程 (其实就是函数的组合)
  • 需要定义一些辅助的基本运算函数

写一个案例吧。
把一个字符串中的首字母提取并转换成大写,使用.作为分隔符。
//world wild web ==>W.W.W

const fp = require("lodash/fp");
const firstLetterToupper = fp.flowRight(
  fp.join(". "),
  fp.map(fp.first),
  fp.map(fp.toUpper),
  fp.split(" ")
);
console.log(firstLetterToupper("world wild web"));

上面例子中用到了两次map,每次map都会对数组进行遍历,会导致性能比较低一些,可以再进行一次组合。

const fp = require("lodash/fp");
const firstLetterToupper = fp.flowRight(
  fp.join(". "),
  fp.map(fp.flowRight(fp.first, fp.toUpper)),
  fp.split(" ")
);
console.log(firstLetterToupper("world wild web"));

结果是一样的
在这里插入图片描述

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值