为什么此 JavaScript switch 语句(在 for 循环内)保留其前一次迭代的值?
Why does this JavaScript switch statement (which is inside a for loop) keep it's values from a previous iteration?
function convertToRoman(num) {
//seperate the number in to singular digits which are strings and pass to array.
var array = ("" + num).split(""),
arrayLength = array.length,
romStr = "";
//Convert the strings in the array to numbers
array = array.map(Number);
//Itterate over every number in the array
for (var i = 0; i < array.length; i++) {
//Calculate what power of ten the digit is by minusing it's index from the array length and passing it to variable "tenToPowerOf"
var tenToPowerOf = arrayLength - array.indexOf(array[i]) - 1,
low = "",
mid = "",
upp = "";
//Set the low, mid and high variables based on their tenToPowerOf value
switch (tenToPowerOf) {
case 0:
low = "I";
mid = "V";
upp = "X";
break;
case 1:
low = "X";
mid = "L";
upp = "C";
break;
case 2:
low = "C";
mid = "D";
upp = "M";
break;
case 3:
low = "M";
mid = "¯V";
upp = "¯X";
break;
}
//Check for digit value and add it's Roman Numeral value (based on it's power from the above switch statement) to romStr
//The problem is, switch "remembers" the value of low, mid and high from the last time it itterated over the number. Thus 99 becomes "XCXC" and not "XCIX".
switch (array[i]) {
case 1:
romStr += low;
break;
case 2:
romStr += low.repeat(2);
break;
case 3:
romStr += low.repeat(3);
break;
case 4:
romStr += low + mid;
break;
case 5:
romStr += mid;
break;
case 6:
romStr += mid + low;
break;
case 7:
romStr += mid + low.repeat(2);
break;
case 8:
romStr += mid + low.repeat(3);
break;
case 9:
romStr += low + upp;
break;
case 10:
romStr += upp;
break;
default:
break;
}
}
//return array;
return romStr;
}
convertToRoman(99);
- 是的,我花了我的份额份额的时间在提问之前寻找相关答案(1.5 小时以上)。
函数将数字转换为罗马数字。
- 它接受一个传递给它的数字参数
- 将数字拆分为数字
- 然后转换为数组
- 然后根据数字的十次方(或与数字长度相关的位置)设置中低值和高值
- 然后按照罗马数字指示的顺序应用这些值并推送到字符串
- 最后返回字符串。
它适用于数字不超过一次的数字。这样做的原因是,当 switch case 在 for 循环中匹配不止一次时,它会应用上一次迭代的低、中和高值。
- 问题在标题中,但我还想请教我正在尝试解决的问题的解决方案。
- 我很乐意提供更多信息并回答每个问题
因为Javascript使用函数闭包并且您的循环默认情况下不会重置值,换句话说,for 内部的变量仍然存在于它外部。
在 for
循环中声明为 var
的变量不会在每次迭代时重置,它与 switch
.
无关
尝试将其粘贴到您的控制台中 -
for (var i = 1; i <= 10; i++)
{
console.log('before', i, j);
var j = i * 10;
console.log('after', i, j);
}
请注意,在第一个循环中,"before" j
是 undefined
,之后总是落后一步。如果您再次 运行 相同的代码,j
将从 100
开始
为了解决这个问题,我会在循环开始时将 j
设置为 null
(或其他一些合理的值)-
for (var i = 1; i <= 10; i++)
{
var j = null;
console.log('before', i, j);
j = i * 10;
console.log('after', i, j);
}
在我看来,您的问题在于使用 array.indexOf(array[i])
来计算幂。你猜怎么着,如果你的数组中有两次相同的值,返回第一个找到的索引,而不是你的当前元素的索引。
猜猜你当前元素的索引是多少? → i
不需要 indexOf
.
与switch
无关。
function convertToRoman(num) {
//seperate the number in to singular digits which are strings and pass to array.
var array = ("" + num).split(""),
arrayLength = array.length,
romStr = "";
//Convert the strings in the array to numbers
array = array.map(Number);
//Itterate over every number in the array
for (var i = 0; i < array.length; i++) {
//Calculate what power of ten the digit is by minusing it's index from the array length and passing it to variable "tenToPowerOf"
var tenToPowerOf = arrayLength - array.indexOf(array[i]) - 1,
low = "",
mid = "",
upp = "";
//Set the low, mid and high variables based on their tenToPowerOf value
switch (tenToPowerOf) {
case 0:
low = "I";
mid = "V";
upp = "X";
break;
case 1:
low = "X";
mid = "L";
upp = "C";
break;
case 2:
low = "C";
mid = "D";
upp = "M";
break;
case 3:
low = "M";
mid = "¯V";
upp = "¯X";
break;
}
//Check for digit value and add it's Roman Numeral value (based on it's power from the above switch statement) to romStr
//The problem is, switch "remembers" the value of low, mid and high from the last time it itterated over the number. Thus 99 becomes "XCXC" and not "XCIX".
switch (array[i]) {
case 1:
romStr += low;
break;
case 2:
romStr += low.repeat(2);
break;
case 3:
romStr += low.repeat(3);
break;
case 4:
romStr += low + mid;
break;
case 5:
romStr += mid;
break;
case 6:
romStr += mid + low;
break;
case 7:
romStr += mid + low.repeat(2);
break;
case 8:
romStr += mid + low.repeat(3);
break;
case 9:
romStr += low + upp;
break;
case 10:
romStr += upp;
break;
default:
break;
}
}
//return array;
return romStr;
}
convertToRoman(99);
- 是的,我花了我的份额份额的时间在提问之前寻找相关答案(1.5 小时以上)。
函数将数字转换为罗马数字。
- 它接受一个传递给它的数字参数
- 将数字拆分为数字
- 然后转换为数组
- 然后根据数字的十次方(或与数字长度相关的位置)设置中低值和高值
- 然后按照罗马数字指示的顺序应用这些值并推送到字符串
- 最后返回字符串。
它适用于数字不超过一次的数字。这样做的原因是,当 switch case 在 for 循环中匹配不止一次时,它会应用上一次迭代的低、中和高值。
- 问题在标题中,但我还想请教我正在尝试解决的问题的解决方案。
- 我很乐意提供更多信息并回答每个问题
因为Javascript使用函数闭包并且您的循环默认情况下不会重置值,换句话说,for 内部的变量仍然存在于它外部。
在 for
循环中声明为 var
的变量不会在每次迭代时重置,它与 switch
.
尝试将其粘贴到您的控制台中 -
for (var i = 1; i <= 10; i++)
{
console.log('before', i, j);
var j = i * 10;
console.log('after', i, j);
}
请注意,在第一个循环中,"before" j
是 undefined
,之后总是落后一步。如果您再次 运行 相同的代码,j
将从 100
为了解决这个问题,我会在循环开始时将 j
设置为 null
(或其他一些合理的值)-
for (var i = 1; i <= 10; i++)
{
var j = null;
console.log('before', i, j);
j = i * 10;
console.log('after', i, j);
}
在我看来,您的问题在于使用 array.indexOf(array[i])
来计算幂。你猜怎么着,如果你的数组中有两次相同的值,返回第一个找到的索引,而不是你的当前元素的索引。
猜猜你当前元素的索引是多少? → i
不需要 indexOf
.
与switch
无关。