Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将函数链的结果传递给函数_Javascript_Functional Programming - Fatal编程技术网

Javascript 将函数链的结果传递给函数

Javascript 将函数链的结果传递给函数,javascript,functional-programming,Javascript,Functional Programming,如果我有一个数组someArray,我首先要对它执行一些操作,然后将结果传递给一个函数arrfun,该函数将数组作为参数。像下面这样 let arr = someArray.filter(foo).map(bar) let result = arrfun(arr) 在上面的场景中,我希望避免必须分配要传递给arrfun的中间变量。我想要这样的东西 Object.prototype.pipe = function(f) {return f(this)} let result = someArr

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

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

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

let result = someArray.filter(foo).map(bar).pipe(arrfun)
  • 代替
    .pipe()
    您将如何解决此问题
  • 将该函数引入
    对象是否明智
  • pipe
    是这种功能的最佳名称吗<代码>链
    <代码>通过
新示例

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)
在上面的示例中,一个问题是如果没有找到匹配项,
.match
将返回
null
。使用
.pipe
您可以通过将该行更改为

.pipe(s => s.match(/--[\w.]* [\w.]*/g) || [])
如果没有
管道
,您将如何解决此问题

在上面的场景中,我希望避免必须分配要传递给
arrfun
的中间变量

你忽略了这个简单、直截了当的表达吗

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

从右到左的功能组合

或者您希望使用经典(从右到左)函数组合

const compose=(f,…fs)=>x=>
f==未定义?x:f(组成(…fs)(x))
常量过滤器=f=>xs=>
xs.filter(x=>f(x))
常量映射=f=>xs=>
映射(x=>f(x))
常量foo=x=>
x>3
常数条=x=>
x*x
常数arrfun=xs=>
xs.reverse()
常量myfunc=
组合(arrfun、映射(bar)、过滤器(foo))
设someArray=[1,2,3,4,5,6]
让结果=myfunc(someArray)
console.log(结果)

//[36,25,16]
您可以首先将操纵器函数和结果函数组合为可重用函数。比如:

let arr = [1,2,3,4,5];
const manipulatorFn = arr => arr.map(item => item +1);
const arrFunc = (arr, fn) => fn(arr);
或者如果你想在arrFunc做更多的事情

const arrFunc = (arr, fn) => {
  let a = fn(arr);

  // do some more stuff with a
  return a;
};
现在您可以获取结果了

let result = arrFunc(arr, manipulatorFn);

我不认为从可读性的角度来包装整个东西。想象一下,您必须将更多的东西链接到arrfun,然后将这些东西包装到另一个函数中。不过我可能忽略了作文。唯一的缺点可能是我必须先定义函数,然后再编写(这可能也是一件好事)。我更新了我的答案以回应您的评论。Identity functor非常适合在不接触本机原型的情况下创建可链接的接口。让我知道,如果我能进一步帮助你^^^^关于你的评论编辑,
foo
bar
不需要预先定义-它们可以是直接用
myfunc
编写的lambda表达式非常好的示例,在那里学到了一些很好的东西,thnx。我在帖子中添加了一个有点不同的额外示例。如果你真的想在
对象.prototype
上引入一个新方法,至少(但不是,)arrfun(someArray.filter(foo.map(bar))有什么问题。意味着一些不同的东西仅仅
(options.join(…).match(…)| |[]).map(…)…
?因为,在我看来,像这样的包装内容在可读性方面是不可伸缩的。我认为在这个例子中,包装的东西太大了,想象一下有更多的包装。只是链接东西要简单得多。