通过功能链的功能来传递结果 [英] Pass result of functional chain to function
问题描述
如果我有一个数组 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屋!