高级前端手写代码【Q657】实现一个 composeLeft/flow(从左向右) 函数,进行函数合成

实现一个 composeLeft/flow(从左向右) 函数,进行函数合成

更多描述 实现一个 composeLeft/flow(从左向右) 函数,进行函数合成,类似于 lodash.flow

const add10 = (x) => x + 10;
const mul10 = (x) => x * 10;
const add100 = (x) => x + 100;
 
// (10 + 10) * 10 + 100 = 300
flow(add10, mul10, add100)(10);

相关问题: 【Q181】如何实现 compose 函数,进行函数合成

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 675

Author 回答者: ovarte

// 我这个好理解,不够优雅

function compose(fn){
    let args = [].slice.call(arguments)
    return function(){
        let sum = 0
        let params = [].slice.call(arguments)[0]
        for(let i = 0; i< args.length; i++){
            let f = args[i]
            sum += f(params)
        }
        return sum;
    }
}

Author 回答者: shfshanyue

@ovarte 使用 markdown 语法做代码高亮吧,这个 Issue 可以重复编辑,多余的 Issue 可以删掉。另外,这个问题和以前的重复了,我改为了从左到右执行了

Author 回答者: shfshanyue

const flow = (...fns) =>
  fns.reduce(
    (f, g) =>
      (...args) =>
        g(f(...args)),
  );

Author 回答者: heretic-G

function compose(...funArr) {
  return function (...args) {
    let result = args;
    for (let i = 0; i < funArr.length; i++) {
      if (typeof funArr[i] === "function") {
        result = [funArr[i](...result)];
      }
    }
    return result.length === 1 ? result[0] : result;
  };
}

Author 回答者: haotie1990

/**
 * 创建一个函数。 返回的结果是调用提供函数的结果,
 * this 会绑定到创建函数。 每一个连续调用,
 * 传入的参数都是前一个函数返回的结果
 * @param {Function|Function[]} funcs 要调用的函数
 */
function flow(funcs) {
  if (!Array.isArray(funcs)) {
    funcs = [funcs];
  }
  const context = this;
  return function () {
    let args = [].slice.call(arguments, 0);
    return funcs.reduce((acc, func) => {
      acc = Array.isArray(acc) ? acc : [acc];
      return func.apply(context, acc);
    }, args);
  };
}
 
const add10 = (x) => x + 10;
const mul10 = (x) => x * 10;
const add100 = (x) => x + 100;
 
console.log(flow([add10, mul10, add100])(10));

Author 回答者: hwb2017

const lodashFlow =
  (...fns) =>
  (...args) =>
    fns.reduce(
      (a, b) => b(+a),
      args.map((a) => +a),
    );
 
const add10 = (x) => x + 10;
const mul10 = (x) => x * 10;
const add100 = (x) => x + 100;
console.log(lodashFlow(add10, mul10, add100)(10));