developer-plus / interview

https://interview.developer-plus.org
MIT License
9 stars 1 forks source link

手写柯里化函数 #21

Open Hongbusi opened 2 years ago

Hongbusi commented 2 years ago
function currying(fn) {
  function curried(...args) {
    // 当已经传入的参数, 大于等于需要的参数时, 就执行函数
    if (args.length >= fn.length) {
      return fn.apply(this, args)
    }
    else {
      // 没有达到个数时, 需要返回一个新的函数, 继续来接受参数
      return function(...args2) {
        // 接受到参数后, 需要递归调用 curried 来检查函数的参数个数时否达到
        return curried.apply(this, [...args, ...args2])
      }
    }
  }

  return curried
}

// test
function add(num1, num2, num3) {
  return num1 + num2 + num3
}

const curryAdd = currying(add)

console.log(curryAdd(10)(20)(30))
console.log(curryAdd(10, 20)(30))
console.log(curryAdd(10, 20, 30))
lyx-jay commented 2 years ago
function curry(fn, args) {
  let length = fn.length;
  args = args || [];
  return function() {
    let _args = args.slice(0);
    let arg;
    for (let i = 0; i < arguments.length; i++) {
      arg = arguments[i];
      _args.push(arg)
    }
    if (_args.length < length) {
      return curry.call(this, fn, _args);
    } else {
      return fn.apply(fn, _args);
    }
  }
}
Hongbusi commented 2 years ago

@lyx-jay 可以配一下代码高亮~

ChenHaoJie9527 commented 2 years ago

简约版

// 柯里化函数
const curry = (func: Function) => {
  return function curryFunc(...args: any[]) {
    // 实参 < 形参, 返回一个函数,并等待接受剩余参数
    if (args.length < func.length) {
      return function () {
        // 合并每次调用函数时传递的参数
        return curryFunc(...[...args, ...Array.from(arguments)]);
      };
    }
    // 当实参 >= 形参时,直接执行函数返回结果
    return func(...args);
  };
};

function test(n1, n2, n3) {
  return n1 + n2 + n3;
}

const result = curry(test);
console.log('sum', result(1)(2)(3)); // 6
console.log('sum', result(1, 2)(1)); // 4
console.log('sum', result(1)(2)(1)); // 4
console.log('sum', result(1, 2, 1)); // 4