使用动态参数进行递归

Rut*_*rde 7 javascript recursion

这是一个我尚未弄清楚的面试问题.考虑以下:

function recurse(a) {
    return function(b) {
        console.log(a + b);
    }
}

//This will log '5' in the console
recurse(2)(3);
Run Code Online (Sandbox Code Playgroud)

现在我被要求编写一个函数,该函数将采用n多个参数并通过记录参数值的最终总和以相同的方式工作.含义:

//This should log '13'
recurse(2)(3)(1)(7)
Run Code Online (Sandbox Code Playgroud)

如何编写这样的函数?我已经尝试过在递归,动态参数等方面进行思考.但是还没有能够记下任何具体的东西.

Nin*_*olz 6

您可以返回函数,实现toStringvalueOf方法.

function recurse(x) {
    var sum = x;  

    function f(y) { 
        sum += y;
        return f;
    }; 
    f.toString = function () { return sum; }; // for expecting string, 1st log
    f.valueOf = function () { return sum; };  // for expecting number, 2nd log

    return f;
}

console.log(recurse(2)(3)(4));
console.log(recurse(2)(3) + recurse(4)(5));
console.log(recurse(2)(40) == 42);  // converts to expected type Number
console.log(recurse(2)(40) === 42); // checks type Function
Run Code Online (Sandbox Code Playgroud)

  • @Dellirium:不,对象定义自己的方法是正常的,包括那些方法.但是*这个使用*可能被称为hack,因为`f = recurse(2)(3)`不是**将把'5`放在`f`中.我们在in-snippet控制台中看到`9`的唯一原因是它调用`toString`; 一个真正的控制台显示一个函数(后跟其toString结果). (2认同)
  • 这是解决问题,但实际问题是需求本身.正如Nina所展示的那样,你可以修改它看起来的功能(和行为类型),就像一个数字,但它没有,这可能会导致问题,当使用这个东西时.因为虽然`console.log(recurse(2)(3),recurse(2)(3)== 5)`将显示`5,true`,但这将失败:`recurse(2)(3)=== 5`.除非你还添加一个`toJSON`函数,否则这个"数字"将在序列化时消失.**结论:**您可以获得有问题的最佳解决方案,并且很可能是错误的(在其中使用,而不是实现) (2认同)

A. *_*dor 6

这是我能想到的最简单的版本:

function add (a) {
  return function (b) {
    return b == null ? a : add(a+b);
  }
}

console.log( 
  add(2)(3)() 
);
console.log(
  add(10)(100)(1000)(4)() 
);
Run Code Online (Sandbox Code Playgroud)

在es6中,它很紧凑!

let add = a => b => b == null ? a : add(a+b);
Run Code Online (Sandbox Code Playgroud)

笔记

您的问题的问题在于函数可以返回aFunction a Number。下面的代码:

let result = add(2)(3);
Run Code Online (Sandbox Code Playgroud)

相当于:

/*1*/ let partialResult = add(2);
/*2*/ let result = partialResult(3);
Run Code Online (Sandbox Code Playgroud)

在第 1 行中,add不知道是否使用最后一个参数调用它!换句话说,它不知道应该partialResult是一个数字,还是一个将用另一个参数调用的函数。

Nina Scholz 为您提供了一个解决方案,当像原语partialResult一样处理时,它的行为就像一个数字,当像函数一样调用时,它的行为就像一个函数。在我的解决方案中,它始终像一个函数一样运行,并且在不带参数调用时返回一个总和。partialResult

第一种方法需要特定于语言的机制,以便在某些条件下“表现得像一个数字”。如果您的面试是关于 JavaScript 的,那么这是最好的近似!但在与语言无关的背景下,您所要求的是不可能的。