简体   繁体   English

递归调用相同的函数

[英]Recursively calling the same function

I was asked to create a function to achieve the following, add up some number and then call the value of them all, ie a chained function of sorts, I created a bad solution, but cannot think of a better way of doing this. 我被要求创建一个函数来实现以下目标,相加一些数字,然后调用它们的全部值,即各种链式函数,我创建了一个不好的解决方案,但想不出更好的方法。

add(5).add(10).add(20).value();

The interview question just started with an empty function 面试问题刚开始是一个空函数

function add() {

}

My solution is below, does anybody have any other suggests as I am interested, I've looked at currying, binding etc but not come up with an elegant solution. 我的解决方案如下,有兴趣的人有没有其他建议,我查看过柯里化,装订等,但没有提出一个优雅的解决方案。

var slice = Array.prototype.slice

function add() {
  var arr = slice.call(arguments);
  return {
    add: function() {
      arr = arr.concat(slice.call(arguments))   
      return this;
    },
    value: function() {
      return arr.reduce(function(prev, curr) {
          return prev + curr;
      });
    }
  }
};

Edit Just to clarify I was wondering if there is a way to do this without returning an add function but to call the existing add function. 编辑只是为了澄清我想知道如果有一种方法可以做到这一点,而不返回一个附加功能,但调用现有的附加功能。 I think the way that it has been done below is nice, but I think the interviewer was looking for something non-simple. 我认为下面的工作方式很好,但是我认为面试官正在寻找一些非简单的东西。

Why so complicated? 为什么这么复杂? Don't carry that array of values around with you. 不要随身携带该值数组。 Also, try to stay functional and don't mutate it. 另外,请尝试保持功能正常,不要对其进行变异。

function add(x) {
    return {
        value: function() {
            return x;
        },
        add: function(y) {
            return add(x+y);
        }
    };
}

The key insight here seems to be that chaining doesn't just mean to return this , but rather any object of the same class. 这里的关键见解似乎是链接不仅意味着return this ,而且意味着同一个类的任何对象。 Immutability dictates that it should be a different object when it has a different sum attached to it. 不变性要求当附加了不同的总和时,它应该是一个不同的对象。

seems overcomplicated tbh, here's my answer but maybe I'm not understanding part of the requirements 似乎太复杂了,这是我的答案,但也许我不了解部分要求

function add(x) {
  return {
    val: 0,
    add: function(x) {
      this.val += x;
      return this;
    },
    value: function() {
      return this.val;
    }
  }
};

I like with your idea of lazy calculation, that's why we should keep the chain of operations. 我喜欢您的惰性计算想法,这就是为什么我们应该保持操作链。 But implementation using array has drawback of mutability (see my comment) 但是使用数组的实现具有可变性的缺点(请参阅我的评论)

I have just written somewhat close to how I see the solution 我刚刚写了一些接近解决方案的方法

var Calculator = function(initialValue){

    function createOperator(operation) {

        return function(value) {
            return createInstance(operation.bind(null, value));
        }
    }

    function createInstance(reduce) {

         return Object.freeze({

                'add':     createOperator((val) => reduce() + val),

                'subtract':  createOperator((val) => reduce() - val),

                'multiply': createOperator((val) => reduce() * val),

                'divide':   createOperator((val) => reduce() / val),

                'value': reduce

            });
     }

    return createInstance(()=>initialValue);
}

Calculator(0).add(5).multiply(4).subtract(12).divide(2).value(); //returns 4    

In your problem lazy calculation in not really required, but if we want to preserve chain of operations for multiple use, here it goes. 在您的问题中,并不是真正需要惰性计算,但是如果我们想保留操作链以供多次使用,那就去吧。 See this example 看这个例子

var Calculation = function(){

    function createOperator(operation) {

        return function(value) {
            return createInstance(operation.bind(null, value));
        }
    }

    function createInstance(apply) {

         return Object.freeze({

                'add':      createOperator((val, initial) => apply(initial) + val),

                'subtract': createOperator((val, initial) => apply(initial) - val),

                'multiply': createOperator((val, initial) => apply(initial) * val),

                'divide':   createOperator((val, initial) => apply(initial) / val),

                'apply':    apply

            });
     }

    return createInstance((initialValue)=>initialValue);

}();

var calc = Calculation.add(5).multiply(2).subtract(11);

calc.apply(2); //returns 3

calc.apply(10); //returns 19

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM