[英]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.