我正在使用javascript lambda表达式进行一些函数式编程实践,并提出了以下代码。该代码旨在返回一个函数,该函数计算给定基数值的给定数量的幂。我的代码如下;
const findUpper = base => (num, i = 0) => {
if (num < base) {
return i;
} else {
i++;
return findUpper(Math.round(num / base), i);
}
}
const findUpper2 = findUpper(2)
console.log(findUpper2(8)) //expected to have 3
这里的问题是,在第一次findUpper
调用后,递归会被破坏,因为它会返回一个函数。
如何使此代码段有效?
答案 0 :(得分:2)
一种方式就是这样
var findUpper = base => {
let fn = (num, i = 0) => {
if (num < base) {
return i;
} else {
i++;
return fn(Math.round(num / base), i);
}
};
return fn;
}
var findUpper2 = findUpper(2)
console.log(findUpper2(8))
使用bothUpper中的名称声明递归函数...递归调用fn而不是findUpper
如果没有不必要地使用箭头功能,它会稍微“整洁”
var findUpper = base => {
return function fn(num, i = 0) {
if (num < base) {
return i;
} else {
i++;
return fn(Math.round(num / base), i);
}
};
}
var findUpper2 = findUpper(2)
console.log(findUpper2(8))
虽然,使用=&gt;代码可以像
一样简单const findUpper = base => {
let fn = (num, i = 0) => (num < base) ? i : fn(Math.round(num / base), i + 1);
return fn;
}
答案 1 :(得分:0)
这是你的错误
i++
return findUpper(Math.round(num / base), i);
您打算:
// don't forget, findUpper is a curried function
return findUpper(Math.round(num/base))(i + 1);
这是将程序编写为纯表达式的另一种方法
const findUpper = (base = 1) => (num = 0, exp = 0) =>
num < base
? exp
: findUpper (base) (num / base, exp + 1)
console.log (findUpper (2) (8))
&#13;
使用通用的loop
/ recur
程序,我们保持findUpper
的参数清洁,提高循环性能,并维护您想要的咖喱界面
const recur = (...values) =>
({ recur, values })
const loop = f =>
{
let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const findUpper = (base = 1) => (num = 0) =>
loop ((n = num, exp = 0) =>
n < base
? exp
: recur (n / base, exp + 1))
console.log (findUpper (2) (8))
&#13;