首页 > 试题广场 >

柯里化

[编程题]柯里化
  • 热度指数:39375 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数
示例1

输入

var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);

输出

6
柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。简单理解题目意思,就是指,我们将预定义的函数的参数逐一传入到curryIt中,当参数全部传入之后,就执行预定义函数。于是,我们首先要获得预定义函数的参数个数fn.length,然后声明一个空数组去存放这些参数。返回一个匿名函数接收参数并执行,当参数个数小于fn.length,则再次返回该匿名函数,继续接收参数并执行,直至参数个数等于fn.length。最后,调用apply执行预定义函数。
function curryIt(fn) {
     //获取fn参数的数量
     var n = fn.length;
     //声明一个数组args
     var args = [];
     //返回一个匿名函数
     return function(arg){
         //将curryIt后面括号中的参数放入数组
         args.push(arg);
         //如果args中的参数个数小于fn函数的参数个数,
         //则执行arguments.callee(其作用是引用当前正在执行的函数,这里是返回的当前匿名函数)。
         //否则,返回fn的调用结果
         if(args.length < n){
            return arguments.callee;
         }else return fn.apply("",args);
     }
 } 

编辑于 2015-08-17 13:45:18 回复(12)
更多回答
function curryIt(fn) {
        var args = [].slice.call(arguments,1);
        return args.length < fn.length ?  function (a) {
            return curryIt.apply(curryIt,[fn].concat(args,a));
        } fn.apply(fn,args) ;
    }
编辑于 2017-03-28 17:59:57 回复(1)
function curryIt(fn) {
    let a = function(val){
        return function(val2){
            return function(val3){
                return fn.call(null,val,val2,val3)
            }
        }
    }
    return a
    
}
发表于 2021-08-12 23:59:21 回复(0)
function curryIt(fn) {
    var len = fn.length;
    var args = [];
    var result = arg => {
        args.push(arg);
        len--;
        return len == 0 ? fn.apply(this, args) : result;
    }
    return result;
}




编辑于 2020-03-25 16:07:18 回复(0)
function curryIt(fn) {
    function a(str1) {
        function b(str2) {
            function c(str3) {
                return fn.call(this, str1, str2, str3)
            }
            c.length = 1;
            return c;
        }
        b.length = 1;
        return b;
    }
    a.length = 1
    return a;
}

发表于 2019-11-04 22:42:59 回复(0)
function curryIt(fn) {
    return function(a){
        return function(b){
            return function(c){
                return fn(a,b,c);
            }
        }
    }
}

发表于 2018-07-05 16:00:27 回复(0)
function curryIt(fn) {
    return function a(one){
        return function b(two){
            return function c(three){
                return fn.call(null,one,two,three);
            }
        }
    }
}//这个能通过测试
发表于 2017-12-05 20:23:20 回复(0)
function curryIt(fn) {
    var a = function(args1){
       var b = function(args2){
           var c = function(args3){
               return fn(args1,args2,args3);
           }
           return c;
       }
       return b;
    }
	return a;
}

测试通过!

发表于 2017-04-10 16:19:55 回复(0)
javascript权威指南p191:  ES5中的bind()方法不仅仅是将函数绑定至一个对象,
而且还附带一些其它应用:  除了第一个实参之外,传入bind()的实参也会绑定至this,
这个附带的应用是一种常见的函数编程技术,  有时也被称为“柯里化”(currying)。
于是就有了这个答案,每次传一个参数。  
the another answer is:
(https://github.com/rmurphey/js-assessment-answers/blob/master/app/functions.js)
  
 
function curryIt(fn){ return function a(arg){  var g=fn.bind(null,arg);  return function b(arg1){  var h=g.bind(null,arg1);  return function c(arg2){  return h(arg2);
            }
        }
    }
}

编辑于 2016-06-15 17:49:57 回复(0)
function curryIt(fn) {
    var a= function(g){
        var b=function(h){
            var c=function(j){
                return fn(g,h,j);
            }
            return c;
        }
        return b;
    }
    return a;
}
发表于 2015-10-19 23:23:47 回复(0)
不用 arguments.callee 的方法,用变量名代替了,大同小异:
function curryIt(fn) {
	var length = fn.length,
		args = [];
    var result =  function (arg){
        args.push(arg);
        length --;
        if(length <= 0 ){
            return fn.apply(this, args);
        } else {
            return result;
        }
    }
    
    return result;
}

发表于 2016-03-24 10:25:54 回复(12)
function curryIt(fn) {
	return function a(xa){
        return function b(xb){
            return function c(xc){
                return fn.call(this,xa,xb,xc);
            };
        };
    };
}

编辑于 2015-08-29 13:43:10 回复(4)
function curryIt(fn) {
  var arr=[],l = fn.length;
  return function(x){  
    arr.push(x);
    return arr.length < l ? arguments.callee : fn.apply(null,arr);
  }
}

发表于 2015-07-12 12:19:56 回复(4)
function curryIt(fn) {
    return (a)=>(b)=>(c)=>fn(a,b,c);
}
es6,浏览器中可以
发表于 2017-09-18 08:57:14 回复(1)
function curryIt(fn) {
    var len = fn.length;
    var args = [];
    var result = function(arg)
    {
        args.push(arg);
        if(--len > 0)
            return result;
        else
            return fn.apply(this,args);
    }
    return result;
}

发表于 2016-10-12 12:51:48 回复(0)
牛客的题好蛋疼 - - !, 还必须限制length为1,一人我饮酒醉.
function curryIt(fn) {
            var len = fn.length,
                args = [];
            return function () {
                args.push([].shift.call(arguments));
                if (args.length < len) {
                    return arguments.callee;
                } else {
                    return fn.apply(null, args);
                }
            }
        }

发表于 2017-03-14 19:29:29 回复(3)
function curryIt(fn) {
  var a=function (A) {
    //var argA=arguments[0];
    var b=function (B) {
      //var argB=arguments[0];
      var c=function (C) {
        //var argC=arguments[0];
        return fn.call(null,A,B,C);
      };
      c.length=1;
      return c;
    };
    b.length=1;
    return b;
  };
  a.length=1;
  return  a;
}

发表于 2016-07-16 21:29:20 回复(0)
函数属于引用类型,所以它们也有属性和方法。 
ECMAScript 定义的属性 length 声明了函数期望的参数个数。 
发表于 2015-07-17 10:56:49 回复(0)
function curryIt(fn) {
    return  (a)=>(b)=>(c)=>a+b+c
}
发表于 2021-08-09 17:10:11 回复(0)
function curryIt(fn) {
    return a => b => c => fn(a, b, c);
}

发表于 2021-07-30 15:59:06 回复(0)

问题信息

难度:
132条回答 19611浏览

热门推荐

通过挑战的用户

查看代码