通过功能链的功能来传递结果 [英] Pass result of functional chain to function

查看:112
本文介绍了通过功能链的功能来传递结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个数组 someArray ,我首先要做一些操作,然后将结果传递给函数 arrfun 将一个数组作为参数。像下面这样:

  let arr = someArray.filter(foo).map(bar)
let result = arrfun(在上面的场景中,我想避免必须分配一个中间变量来传递给中间变量 arrfun 。我想这样的东西。

  Object.prototype.pipe = function(f){return f(this)} 

result result = someArray.filter(foo).map(bar).pipe(arrfun)




  • 代替 .pipe()您如何解决这个问题?

  • 将该函数引入 Object

  • pipe >这样的功能的最好的名字? 传递



新示例

  const pc = options =>选项
.join('')
.match(/ - [\w。] * [\w。] * / g)
.map(s => s .slice(2).split(''))
.map(([key,value])=>({key,value}))
.map(nestObject)
((acc,val)=> Object.assign(acc,val),{})

const nestObject =({key,value})=> $ {
.split('。')
.reverse()
.reduce((inner,key)=>({[key]:inner}),value)

在上面的例子中,一个问题是 .match 返回 null 如果找不到匹配项。使用 .pipe 你可以解决它,只要将该行更改为

 。 pipe(s => s.match(/  -  [\ w。] * [\w。] * / g)|| [])

如果没有 pipe

在上面的场景中,我想避免必须分配一个中间变量来传递给 arrfun

您是否忽略了这种简单明了的表达方式?

  let result = arrfun(someArray.filter(foo).map(bar))






从右到左的功能组合

(从右到左)函数组合?



  const compose =(f,... fs)=> x => f === undefined? x:f(compose(... fs)(x))const filter = f => xs => xs.filter(x => f(x))const map = f => xs => xs.map(x => f(x))const foo = x => x> 3 const bar = x => x * x const arrfun = xs => xs.reverse()const myfunc = compose(arrfun,map(bar),filter(foo))let someArray = [1,2,3,4,5,6] let result = myfunc(someArray)console.log(result )// [36,25,16]  






从左至右的函数组合

使用从左至右的函数组合

const compose =(f,... fs)=> x => f === undefined? x:compose(... fs)(f(x))const filter = f => xs => xs.filter(x => f(x))const map = f => xs => xs.map(x => f(x))const foo = x => x> 3 const bar = x => x * x const arrfun = xs => xs.reverse()//注意functionsconst的顺序myfunc = compose(filter(foo),map(bar),arrfun)let someArray = [1,2,3,4,5,6] let result = myfunc(someArray) console.log(result)// [36,25,16]



< hr>

身份函子


我不认为包裹整个事情在可读性方面有所扩展。想象一下,你必须将更多的东西链接到arrfun,然后将这个东西包装在另一个函数中。

你应该看到这个答案我写了关于身份仿函数 - 这给你一个可链接的接口,但没有触及原生原型



const Identity = x => ({runIdentity:x,map:f => Identity(f(x))})const foo = x => x> 3 const bar = x => x * x const arrfun = xs => xs.reverse()const myfunc = xs => Identity(xs).map(xs => xs.filter(foo)).map(xs => xs.map(bar)).map(xs => arrfun(xs)).runIdentitylet someArray = [1 ,2,3,4,5,6] let result = myfunc(someArray)console.log(result)// [35,25,16]



当然,如果您保留过滤器 map ,就像我们之前定义的那样,它清理了 myfunc



  const Identity = x => ({runIdentity:x,map:f => Identity(f(x))})const filter = f => xs => xs.filter(x => f(x))const map = f => xs => xs.map(x => f(x))const foo = x => x> 3 const bar = x => x * x const arrfun = xs => xs.reverse()const myfunc = x => Identity(x).map(filter(foo)).map(map(bar)).map(arrfun).runIdentitylet someArray = [1,2,3,4,5,6] let result = myfunc(someArray)console .log(result)// [35,25,16]  

不要挂在先前定义的 foo bar 上。我们可以直接在 myfunc 中使用lambda表达式,如果您想要的话

  const myfunc = xs => 
.map(xs => xs.filter(x => x> 3))
.map(xs => xs.map(x = > x * x))
.map(arrfun)
//或者跳过在其他地方定义arrfun并且只是...
// .map(xs => xs.reverse( ))
.runIdentity


If I have an array someArray that I first want to do some operations on and then pass that result to a function arrfun that takes an array as an argument. Like the following

let arr = someArray.filter(foo).map(bar)
let result = arrfun(arr)

In the above scenario I would like to avoid having to assign an intermediary variable to be passed to arrfun. I would like to have something like this.

Object.prototype.pipe = function(f) {return f(this)}

let result = someArray.filter(foo).map(bar).pipe(arrfun)

  • In lieu of a .pipe() how would you solve this?
  • Would it be sensible to introduce that function to Object?
  • Is pipe the best name for such a function? chain? pass?

New example

const pc = options => options
  .join(' ')
  .match(/--[\w.]* [\w.]*/g)
  .map(s => s.slice(2).split(' '))
  .map(([key, value]) => ({key, value}))
  .map(nestObject)
  .reduce((acc, val) => Object.assign(acc, val), {})

const nestObject = ({key, value}) => key
  .split('.')
  .reverse()
  .reduce((inner, key) => ({[key]: inner}), value)

In the above example a problem is that .match returns null if no match is found. Using .pipe you could solve it ny changing that line to

.pipe(s => s.match(/--[\w.]* [\w.]*/g) || [])

How would you solve this one without pipe?

解决方案

In the above scenario I would like to avoid having to assign an intermediary variable to be passed to arrfun.

Are you overlooking this simple, straightforward expression ?

let result = arrfun(someArray.filter(foo).map(bar))


right-to-left function composition

Or maybe you wish for classic (right-to-left) function composition?

const compose = (f,...fs) => x =>
  f === undefined ? x : f(compose(...fs)(x))

const filter = f => xs =>
  xs.filter(x => f(x))

const map = f => xs =>
  xs.map(x => f(x))

const foo = x =>
  x > 3
  
const bar = x =>
  x * x
  
const arrfun = xs =>
  xs.reverse()

const myfunc =
  compose(arrfun, map(bar), filter(foo))

let someArray = [1,2,3,4,5,6]

let result = myfunc(someArray)

console.log(result)
// [ 36, 25, 16 ]


left-to-right function composition

The same answer as above using left-to-right function composition

const compose = (f,...fs) => x =>
  f === undefined ? x : compose(...fs)(f(x))

const filter = f => xs =>
  xs.filter(x => f(x))

const map = f => xs =>
  xs.map(x => f(x))

const foo = x =>
  x > 3
  
const bar = x =>
  x * x
  
const arrfun = xs =>
  xs.reverse()

// notice order of functions
const myfunc =
  compose(filter(foo), map(bar), arrfun)
  
let someArray = [1,2,3,4,5,6]

let result = myfunc(someArray)

console.log(result)
// [ 36, 25, 16 ]


Identity functor

I dont think wrapping the entire thing scales in terms of readability. Imagine that you have to chain some more stuff to arrfun and then wrap that thing in yet another function.

You should see this answer I wrote about the Identity functor - This gives you a chainable interface but doesn't touch native prototypes

const Identity = x => ({
  runIdentity: x,
  map: f => Identity(f(x))
})

const foo = x =>
  x > 3
  
const bar = x =>
  x * x
  
const arrfun = xs =>
  xs.reverse()

const myfunc = xs =>
  Identity(xs)
    .map(xs => xs.filter(foo))
    .map(xs => xs.map(bar))
    .map(xs => arrfun(xs))
    .runIdentity

let someArray = [1,2,3,4,5,6]

let result = myfunc(someArray)

console.log(result)
// [ 35, 25, 16 ]

Of course if you keep filter and map as we defined before, it cleans up the definition of myfunc

const Identity = x => ({
  runIdentity: x,
  map: f => Identity(f(x))
})

const filter = f => xs =>
  xs.filter(x => f(x))

const map = f => xs =>
  xs.map(x => f(x))

const foo = x =>
  x > 3
  
const bar = x =>
  x * x
  
const arrfun = xs =>
  xs.reverse()

const myfunc = x =>
  Identity(x)
    .map(filter(foo))
    .map(map(bar))
    .map(arrfun)
    .runIdentity

let someArray = [1,2,3,4,5,6]

let result = myfunc(someArray)

console.log(result)
// [ 35, 25, 16 ]

And don't get hung up on foo and bar being defined up front. We can use lambda expressions directly within myfunc if you wanted to

const myfunc = xs =>
  Identity(xs)
    .map(xs => xs.filter(x => x > 3))
    .map(xs => xs.map(x => x * x))
    .map(arrfun)
    // or skip defining arrfun somewhere else and just ...
    // .map(xs => xs.reverse())
    .runIdentity

这篇关于通过功能链的功能来传递结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆