js-ramda-流相关函数

函数形式转换查询表

R.ap

先转换后将自己和转换的值作为参数传入函数处理。仅限于两个函数,都处理同一个参数
循环函数,依次调用参数为数组的子元素,并返回函数调用结果,最后铺平
函数(多)对参数(多)的关系
一般转换方式:[[fn1(n), fn1(n1), fn1(n2)], [fn2(n), fn2(n1), fn2(n2)]] => R.ap[fn1, fn2]([n, n1, n2])
特殊转换方式(两个函数作为参数时):v => firstFn(v, nextFn(v)) => R.ap(firstFn, nextFn)(v)

// 一般转换方式
const fn = R.ap([R.add(1), R.add(2)]); //=> [2, 4, 6, 4, 5, 6]
let r2 = fn([1,2,3])
console.log(r2) // flatten后的结果
// 特殊转换方式
// 调用第一个函数后得到结果1,结果1和自己作为参数传入第二个函数调用。
R.ap(R.concat, R.toUpper)('Ramda') //=> 'RamdaRAMDA'

R.juxt

循环函数,传入一个参数,函数依次调用参数,返回结果
函数(多)对参数(1)的关系

[fn1(n), fn2(n)] => R.juxt([fn1, fn2])(n)
const jfn = R.juxt([R.add(2), R.add(1)]); //=> [2, 4, 6, 4, 5, 6]
let r3 = jfn(1) // [3, 2]
console.log(r3)

R.on

P combinator (粘合函数):将两个值同时经过一个函数调用后,将两者的结果作为参数传入最终的函数进行最后处理。可以看作是R.coverage的定制版本(注1)
接收一个二元函数 f,一个一元函数 g 和两个值。将两个值应用到函数 g 上,在把返回的结果应用到函数 f 上。

注1:R.coverage可以多分支,这里是两个分支,主要区别是R.on两个数据都是经过同一个函数处理,而R.coverage是不同函数(当然也可以同个函数)处理,所以经过不同函数处理使用R.coverage,同个函数处理使用R.on,另外一个区别是,R.on接受两个参数

特点总结:

  • 两个参数
  • 同一个函数处理过程
  • 最后被作为参数传参给总函数调用
// f(g(v1), g(v2)) => R.on(f, g)(v1, v2)
// const eqBy = R.on((a, b) => a === b);
// let r = eqBy(R.prop('a'), {b:0, a:1}, {a:1}) //=> true;
// console.log(r) // true
const containsInsensitive = R.on(R.includes, R.toLower); // 文档里面有误
let r2 = containsInsensitive('o', 'FOO'); //=> true
console.log(r2) // true

R.promap

促销活动,当前,先后函数
函数调用一个参数将结果依次传递给其他两个函数
转换方式:g(h(f(x))) => promap(f, g, h)(x)

const a = R.append(4)
const b = R.prepend(2)
const c = R.concat([3])
// const c = R.take(2)
let fn = R.promap(a, c, b)
let r = fn([1,2,3])
console.log(r)

R.sequence

生成数组序列,并保留参数自身,这里暂时理解为:用于生成参数,方便传参。
将一个 Applicative 的 Traversable 转换成一个 Traversable 类型的 Applicative
Traversable 可穿越的
对一个参数经过各个函数处理后,返回处理的结果数组,并加上
转换方式:[[fn1(v), fn2(v), fn3(v)], fn()(v)] => R.sequence(fn, [fn1, fn2, fn3])(v)


const add = (n) => (x) => R.add(x, n)
let r3 = R.sequence(R.always(R.identity), [add(1), add(2), add(3)]);   //=> Just([1, 2, 3])
console.log(r3([1])) // [2,3,4,1]
const sequence = R.curry((fisrtFn, aryFn, v) => {
  return R.concat(R.map(f => f(v), aryFn), fisrtFn()(v))
})
let r4 = sequence(R.always(R.identity), [add(1), add(2), add(3)])
console.log(r4([1])) // [2,3,4,1]

多个参数的第一个参数相同则可以简写。fn2必须是R.map函数,参数必须是数组

// R.sequence(fn, fn2(ary)) => fn2 => R.map(n => v => { //...coding } )
// 多对一调用合并,并保留一这个参数
const Just = R.map(n => v => R.add(n, v))
let r5 = R.sequence(R.always(R.identity), Just([1, 2, 3])); //=> [Just(1), Just(2), Just(3)]
console.log(r5([1])) // [2,3,4,1]

不传参数的情况下,直接执行fn主函数并返回。

const Nothing = () => () => R.always()
let r6 = R.sequence(R.always(R.identity), Nothing());      //=> [Nothing()]
console.log(r6(123)) // [[]]

R.chain

如果第二个参数是函数,chain(f, g)(x) 等价于 f(g(x), x)
转换方式:f(g(x), x) => chain(f, g)(x)

// 分两种情况
// eg.1 每个函数调用一次,生成数组元素对应的数据.
// 区别于R.juxt(返回数据是数组),R.chain可以返回函数。
R.chain(at, modalKeys) // => [atModalKeys[0], atModalKeys[1]] 生成两个函数
// eg.2 每个函数调用一次,改变原来的数据
R.chain(R.append, R.head)([1, 2, 3]); //=> [1, 2, 3, 1]

R.converge

多个分支,将子分支的调用结果作为参数传入一个函数调用
被称为聚合再聚合

// converge
R.converge(
  R.equals,
  [
    R.length, 
    R.pipe(R.intersection(v), R.length)
  ]
)(ary)

R.compose&R.pipe

经常使用就不贴例子了,为了阐明作用,这里主要说明如下:

  1. R.compose转换方式 => fn1(fn2(fn3(params))) => R.compose(fn1, fn2, fn3)(params) 跟平时写法顺序一致。写法转换使用compose
  2. R.pipe转换方式 => fn1(fn2(fn3(params))) => R.compose(fn3, fn2, fn1)(params) 跟数据流向思路一致。强调数据流向使用pipe;另外如果参数是通过函数生成的,会使用到R.apply(R.pipe, fns)的写法。

R.composeWith&R.pipeWith

该Api主要是多了一个每调用一次函数后将结果进行处理的过程,比如参数防空验证
先执行第一个函数,第二个函数才开始进行with调用
注意:传参是函数数组

const handleFn = (fn, res) => {
  console.log('验证参数')
  return R.isNil(res) ? res : fn(res)
}
const composeWhileNotNil = R.composeWith(handleFn);
// let r = composeWhileNotNil([R.inc, R.prop('age')])({age: 1}) //=> 2
// let r2 = composeWhileNotNil([R.inc, R.prop('age')])({}) //=> undefined
// console.log(r, r2)

const fn = v => {
  console.log('v', v)
  return v
}
let r3 = composeWhileNotNil([
  // R.inc,
  fn,
  R.prop('age'),
  fn,
])({age: 1}) //=> undefined
console.log(r3)
/* 
  v { age: 1 }
  验证参数
  验证参数
  v 1
  1
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值