Fe-interview: 第 15 题:实现 add(1)(2)(3)

Created on 19 Jun 2020  ·  10Comments  ·  Source: lgwebdream/FE-Interview

欢迎在下方发表您的优质见解

JavaScript 滴滴

Most helpful comment

考点:函数柯里化

函数柯里化概念: 柯里化(Currying)是把接受多个参数的函数转变为接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术。

1)粗暴版

function add (a) {
    return function (b) {
        return function (c) {
            return a + b + c;
        }
    }
}
console.log(add(1)(2)(3)); // 6

2)柯里化解决方案

  • 参数长度固定
const curry = (fn) =>
(judge = (...args) =>
    args.length === fn.length
    ? fn(...args)
    : (...arg) => judge(...args, ...arg));
const add = (a, b, c) => a + b + c;
const curryAdd = curry(add);
console.log(curryAdd(1)(2)(3)); // 6
console.log(curryAdd(1, 2)(3)); // 6
console.log(curryAdd(1)(2, 3)); // 6
  • 参数长度不固定
function add (...args) {
    //求和
    return args.reduce((a, b) => a + b)
}

function currying (fn) {
    let args = []
    return function temp (...newArgs) {
        if (newArgs.length) {
            args = [
                ...args,
                ...newArgs
            ]
            return temp
        } else {
            let val = fn.apply(this, args)
            args = [] //保证再次调用时清空
            return val
        }
    }
}

let addCurry = currying(add)
console.log(addCurry(1)(2)(3)(4, 5)())  //15
console.log(addCurry(1)(2)(3, 4, 5)())  //15
console.log(addCurry(1)(2, 3, 4, 5)())  //15

All 10 comments

考点:函数柯里化

函数柯里化概念: 柯里化(Currying)是把接受多个参数的函数转变为接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术。

1)粗暴版

function add (a) {
    return function (b) {
        return function (c) {
            return a + b + c;
        }
    }
}
console.log(add(1)(2)(3)); // 6

2)柯里化解决方案

  • 参数长度固定
const curry = (fn) =>
(judge = (...args) =>
    args.length === fn.length
    ? fn(...args)
    : (...arg) => judge(...args, ...arg));
const add = (a, b, c) => a + b + c;
const curryAdd = curry(add);
console.log(curryAdd(1)(2)(3)); // 6
console.log(curryAdd(1, 2)(3)); // 6
console.log(curryAdd(1)(2, 3)); // 6
  • 参数长度不固定
function add (...args) {
    //求和
    return args.reduce((a, b) => a + b)
}

function currying (fn) {
    let args = []
    return function temp (...newArgs) {
        if (newArgs.length) {
            args = [
                ...args,
                ...newArgs
            ]
            return temp
        } else {
            let val = fn.apply(this, args)
            args = [] //保证再次调用时清空
            return val
        }
    }
}

let addCurry = currying(add)
console.log(addCurry(1)(2)(3)(4, 5)())  //15
console.log(addCurry(1)(2)(3, 4, 5)())  //15
console.log(addCurry(1)(2, 3, 4, 5)())  //15
function currying(){
    let args = [...arguments]
    temp.getValue = ()=>{
        return args.reduce((a,b)=> a + b, 0)
    }
    function temp(...arg){
        if(arg.length){
            args = [
                ...args,
                ...arg
            ]
            return temp
        }
    }
    return temp
}
const add = (a: number, b: number, c: number) => a + b + c;

const adding = (...args: number[]) => args.reduce((pre, cur) => pre + cur, 0);

//参数确定
const curry = (fn: Function) => {
  let args = [];

  return function temp(...newArgs) {
    args.push(...newArgs);
    if (args.length === fn.length) {
      const val = fn.apply(this, args);
      args = [];
      return val;
    } else {
      return temp;
    }
  };
};

//参数不确定
const currying = (fn: Function) => {
  let args = [];

  return function temp(...newArgs) {
    if (newArgs.length) {
      args.push(...newArgs);
      return temp;
    } else {
      const val = fn.apply(this, args);
      args = [];
      return val;
    }
  };
};

const curryAdd = curry(add);
console.log(curryAdd(1)(2)(3)); // 6
console.log(curryAdd(1, 2)(3)); // 6
console.log(curryAdd(1)(2, 3)); // 6

let addCurry = currying(adding);
console.log(addCurry(1)(2)(3)(4, 5)()); //15
console.log(addCurry(1)(2)(3, 4, 5)()); //15
console.log(addCurry(1)(2, 3, 4, 5)()); //15

function curring(fn,arr = []){
  var length = fn.length;
  return (...args) => {
   const currentArr = [...arr.push(args)]
   if(arr.length < length){
        return curring(fn,currentArr];
    } else {
         fn(...currentArr )
    }
  }
}
function currying(fn, args = []) {
    return function temp(...innerArgs) {
        if (innerArgs.length > 0) {
            // 收集后面传入的参数
            args = [...args, ...innerArgs];
            // 返回函数供后面可以继续调用
            return temp;
        } else {
            const val = fn.apply(this, args);
            // 清空参数数组,为了保证下次执行函数可以继续迭代
            args = [];
            return val;
        }
    }
}
// 求和函数
const add = (...args) => args.reduce((a, b) => a + b);
let addCurry = currying(add)
console.log(addCurry(1)(2)(3)(4, 5)())  //15
console.log(addCurry(1)(2)(3, 4, 5)())  //15
console.log(addCurry(1)(2, 3, 4, 5)())  //15

除了typeof为function 正常运算都没问题
function add(num) {
const add2 = (num2) => {
num = num + num2;
add2.toString = () => num;
return add2;
}
return add2;
}
add(1)(2)(3) + 5 // 11
add(1)(2)(3)(4) // ƒ 10

有个疑问,就是参数长度不固定时,addCurry(1)(2)(3)(4, 5)(),最后的需要加函数执行的(),但是题目不是没有吗,也就是只要addCurry(1)(2)(3)(4, 5)这样

function curry(fn, ...args) {
    if (args.length >= fn.length) {
        return fn(...args);
    }

    return (...args2) => curry(fn, ...args, ...args2);
}

function sum(a, b, c) {
    return a + b + c;
}

let add = curry(sum);

console.log(add(1)(2)(3));

js function add (...params) { let result = params.reduceRight((a, b) => a + b) const tmp = (...paramsInit) => { result = [...paramsInit, result].reduceRight((a, b) => a + b) return tmp } tmp.toString = () => `${result}` tmp.valueOf = () => result return tmp }
可以这样实现
@ABoyCDog

const curryAdd = (...args) => {
  const Add = (...args2) => {
    return curry(...args, ...args2)
  }
  Add.toString = () => args.reduce((t, v) => t+v);

  return Add
}

console.log(curryAdd(1)(2)(3,4))
Was this page helpful?
0 / 5 - 0 ratings