我正在将一个项目从Python过渡到Node.js-到目前为止一切都很好。我有一个功能,应该将某人拥有的EXP数量转换为一个级别。我试图将工作功能从Python重写为Node.js,但是功能返回的答案完全不同,我不知道为什么。
Python:
def calculateLevel(exp):
if exp < 83: return 1
else:
calcExp = 0
for level in range(1, 1000):
diff = int(level + 300 * math.pow(2, float(level)/7))
calcExp += diff
if exp < calcExp//4:
break
return level
Node.js:
const _ = require("underscore");
// ...
function calculateLevel(exp) {
return new Promise((resolve, reject) => {
if (exp < 83) resolve(1);
else {
var calcExp = 0;
for (var i in _.range(1, 1000)) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
}
}
});
}
例如,Python中的calculateLevel(123456)
返回51
(正确答案),而Node.js中的await calculateLevel(123456);
返回15
(错误答案)。
很明显,Node.js版本出了点问题,但我不知道这是什么。
任何帮助将不胜感激。预先感谢。
答案 0 :(得分:2)
在Python中:
for i in range(1, 10)
print(i)
将创建序列到1 2 3 4 5 6 7 8 9
JavaScript中的for...in
将遍历键而不是值。
因此for (var i in _.range(1, 1000)) {
将始终为0 ... 999
将其更改为for...of
function calculateLevel(exp) {
return new Promise((resolve, reject) => {
if (exp < 83) resolve(1);
else {
var calcExp = 0;
for (var i of _.range(1, 999)) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
}
}
});
}
此外,不清楚为什么在此处使用Promise,因为此处没有任何异步代码。因此,您可以在此处完全删除Promise。
const _ = require("underscore");
// ...
function calculateLevel(exp) {
if (exp < 83) return 1;
else {
var calcExp = 0;
for (var i of _.range(1, 1000)) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
break;
}
}
return i;
}
}
console.log(calculateLevel(123456))
答案 1 :(得分:0)
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
应该是
if (exp < Math.floor(calcExp/4)) {
break;
}
resolve(i)
答案 2 :(得分:0)
我运行了这段代码:
function calculateLevel(exp) {
return new Promise((resolve, reject) => {
if (exp < 83) resolve(1);
else {
var calcExp = 0;
for (var i=1; i<1000; i++) {
calcExp += parseInt(i + 300 * Math.pow(2, i/7));
if (exp < Math.floor(calcExp/4)) {
resolve(i);
break;
}
}
}
}); }
console.log(calculateLevel(123456));
返回51。
可能是其他原因造成的。
答案 3 :(得分:0)
添加我的意见,因为您已经有了一个可以接受的答案。
尽管您将Python代码块转换为Javascript,但我觉得您实际上不必使用相同的语法和方法名称。
例如,如果我们在Python和JS中采用以下代码块;
Python:
def calculateLevel(exp):
if exp < 83: return 1
else:
calcExp = 0
for level in range(1, 1000):
diff = int(level + 300 * math.pow(2, float(level)/7))
calcExp += diff
if exp < calcExp//4:
break
return level
注意:这里使用for level in range(1, 1000):
。
同样可以通过使用while
循环来完成。所以看起来可能像这样:
level = 0
while level <= 1000:
diff = int(level + 300 * math.pow(2, float(level)/7))
calcExp += diff
if exp < calcExp//4:
break
return level
但是在Python中循环for in range()
比使用while
循环更有效。如果运行简单的基准测试,则可以看到以下结果。
for in range()
:在0.000秒内调用55个函数
while
:在0.001秒内调用1650个函数
尽管Python就是这种情况,但Javascript(和使用下划线的range()
函数的方法)却大不相同。尽管函数名看起来很相似,但这并不意味着它们的性能与Python。
实际上,循环_.range()
比循环while
慢得多。如果您查看一些基准测试结果,将会看到类似以下的内容:
Using _.range(1, 1000)
:慢67.67%
https://jsbench.me/b2jl4vvgnw/1
因此,我认为最好使用while循环编写此代码,并稍作修改,将其编写为:
function calculateLevel(exp) {
var level = 1;
if (exp > 83){
var calcExp = 0;
while(level <= 1000){
calcExp += parseInt(level + 300 * Math.pow(2, level/7));
if (exp < Math.floor(calcExp/4))
break;
level++;
}
}
return level;
}
希望有帮助!