我如何拥有一个JavaScript函数让我们说piper()
,它将几个函数作为参数,并返回一个新函数,将其参数传递给第一个函数,然后将结果传递给第二,然后
将第二个结果传递给第三个,依此类推,最后返回最后一个函数的输出。
piper(foo, fee, faa)(10, 20, 30)
之类的内容相当于调用faa(fee(foo(10,20,30)))
。
PS: 这是我几天前做的一次采访的一部分。
答案 0 :(得分:8)
对于arbritrary函数,您可以使用此ES6函数:
Stream<String> first = Arrays.asList("a", "b", "c").stream();
Stream<String> second = Arrays.asList("a", "x", "c").stream ();
ES5语法相同:
function piper(...fs) {
return (...args) => fs.reduce((args,f) => [f.apply(this,args)],args)[0];
}
// Example call:
var result = piper(Math.min, Math.abs, Math.sqrt)(16, -9, 0)
// Output result:
console.log(result);
答案 1 :(得分:2)
享受。纯ES5解决方案。保留this
。
function piper(){
var i = arguments.length,
piped = arguments[ --i ];
while( --i >= 0 ){
piped = pipeTwo( arguments[ i ], piped );
}
return piped;
}
function pipeTwo( a, b ){
return function(){
return a.call( this, b.apply( this, arguments ) );
}
}
或者,如果你想要花哨的解决方案。
function piperES6( ...args ){
return args.reverse().reduce( pipeTwo );
}
根据所需的方向,可以反转循环。
答案 2 :(得分:1)
非常类似于@trincot's answer(保留上下文),但是按正确顺序编写并且速度稍快,因为它不会创建中间数组:
const piper = (...steps) => function(...arguments) {
let value = steps[0].apply(this, arguments);
for (let i = 1; i < steps.length; ++i) {
value = steps[i].call(this, value);
}
return value;
};
// Usage:
let p = piper(
x => x + 1,
x => x * 2,
x => x - 1
);
console.log(p(2)); // 5
答案 3 :(得分:0)
这里是涉及方法链的另一种答案。我将使用ES6,尽管当然可以将其转换为ES5。该解决方案的好处是它具有非常简洁的TypeScript副本,具有完美的可键入性。
Model
答案 4 :(得分:-1)
function f(f1, f2, f3){
return (args => f3(f2(f1(args))));
}
答案 5 :(得分:-2)
我认为你要做的就是链接。
var funct={
total:0,
add:function(a) {
console.log(funct.total,funct.total+a);
funct.total+=a;
return funct;
}
};
funct.add(5).add(6).add(9);