为什么这个 JavaScript switch 语句(在 for 循环内)保留了上一次迭代的值

Why does this JavaScript switch statement (which is inside a for loop) keep it's values from a previous iteration?

本文关键字:保留 上一次 迭代 循环 for JavaScript switch 语句 为什么      更新时间:2024-03-08
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 +小时(。
  • 该函数将数字转换为罗马数字。

    • 需要一个传递给它的数字参数
    • 将数字拆分为数字
    • 然后转换为数组
    • 然后根据数字的十次幂(或与数字长度相关的位置(设置中低值和高值
    • 然后按罗马数字规定的顺序应用这些值并推送到字符串
    • 最后,返回字符串。
  • 它适用于数字出现不超过一次的数字。这是因为当开关大小写在 for 循环中多次匹配时,它会应用上一次迭代中的低、中和高值。

  • 问题在标题中,但我也想要求解决我试图解决的问题。
  • 我很乐意提供更多信息,并回答每一个问题
在我看来,

你的问题在于使用array.indexOf(array[i])来计算功率。猜猜怎么着,如果你的数组中有两次相同的值,则返回第一个找到的索引,而不是当前元素的索引。

猜你当前元素的索引到底是多少?→ i
无需indexOf.

switch无关.

因为 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);
}

请注意,在第一个循环中,"之前"jundefined,然后之后总是落后一步。如果再次运行相同的代码,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);
}