JavaScript中的管道功能

时间:2016-10-12 20:23:42

标签: javascript ecmascript-6

我如何拥有一个JavaScript函数让我们说piper(),它将几个函数作为参数,并返回一个新函数,将其参数传递给第一个函数,然后将结果传递给第二,然后 将第二个结果传递给第三个,依此类推,最后返回最后一个函数的输出。

piper(foo, fee, faa)(10, 20, 30)之类的内容相当于调用faa(fee(foo(10,20,30)))

PS: 这是我几天前做的一次采访的一部分。

6 个答案:

答案 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);