【问题标题】:For Loop Creates An Infinite Loop When It Detects A Non-Alphabetical CharacterFor 循环在检测到非字母字符时创建一个无限循环
【发布时间】:2019-10-17 20:31:09
【问题描述】:

在 for 循环迭代期间,如果在 if 语句中检测到非字母字符,则 i 不会递增。

如果字符是非字母字符,则非数字函数返回 true,否则返回 false。当我在 for 循环中测试代码时,我让控制台打印出 i 的值。每当代码到达非字母字符时,我都不会递增,因此会创建一个无限的 for 循环。

function isUpper(str){
  for(i = 0; i < str.length; i++){
    if(str.charAt(i) == str.charAt(i).toUpperCase()){
      if(!nonnumeric(str.charAt(i))){
        return true;
      };
    };
  };
  return false;
};

如果字符串中有大写字符,我希望它返回 true。如果字符串中没有大写字符,我希望它返回 false。

【问题讨论】:

  • 我认为您误解了结果。您能否说明您是如何得出正在发生无限循环的结论的?所说的 for 循环中的任何内容都不会阻止 i 在不停止循环的情况下递增。
  • 循环将运行 N 次,其中 N 是 str 的长度。要制作这个 inf,您需要在计算每个迭代 str.length 时以 >= 迭代速度的速率添加到字符串中。
  • 如果字符是非字母字符而不是非数字字符,为什么nonnumeric() 返回 true?
  • 我看到你没有声明 i 这里有varlet; nonnumeric 或其他东西是否有可能覆盖您的全局 i 变量,也许?也许摆出你的nonnumeric 功能会帮助我们。
  • 我不敢相信我犯了这么愚蠢的错误。 @Jacob 感谢您指出这一点。问题是我忘记用let 声明i 并且非数字覆盖了全局变量i

标签: javascript infinite-loop


【解决方案1】:

如果您要检查整个字符串是否为大写,您可以做一些更简单的事情。

function isUpper(str) {
  return /^[A-Z\s\W]+$/.test(str);
}

console.log(isUpper('ALL UPPER CASE'));
console.log(isUpper('ALL UPPER CASE! WITH ~@# STUFF'));
console.log(isUpper('THIS hAS ONE LOWER CASE CHARACTER'));
console.log(isUpper('THIS HAS 1 NUMBER'));

说明

正则表达式检查从开始 (^) 到结束 ($) 的整个字符串是否与 [] 中包含的字符匹配,[] 的范围从大写 A 到大写 Z (A-Z,特殊的“空格”字符\s,以及其他非单词字符\W,匹配一次或多次。您可以对其进行微调以确保它至少匹配一个大写字母,后跟可选的空格、逗号,感叹号等。这完全取决于您的用例以及预期的输入与输出将是什么

编辑

代码下最后一句没看懂。如果您只想检查字符串中某处的大写字符,您可以简单地拥有

function isUpper(str) {
  return /[A-Z]/.test(str)
}

console.log(isUpper('ALL UPPER CASE'));
console.log(isUpper('ALL UPPER CASE! WITH ~@# STUFF'));
console.log(isUpper('THIS hAS ONE LOWER CASE CHARACTER'));
console.log(isUpper('THIS HAS 1 NUMBER'));
console.log(isUpper('this has no uppercase characters at all'));

【讨论】:

    【解决方案2】:

    我认为导致问题的几件事:

    1. 您正在逐个查看字符串中的每个字符,然后返回真或假。如果您的目标是确定字符串是否至少包含一个大写字母,那么您首先需要遍历整个字符串。现在,如果您的第一个字符不是大写,它不会返回 true,因此会立即返回 false。
    2. 当您遍历字符串时,您会遇到非字母字符,例如空格和标点符号。如果您测试“小写”期间是否等于“大写”期间,它将评估为真,这可能会引发误报。

    解决方案: 我稍微改变了功能。现在,它遍历整个字符串并使用正则表达式(“Regex”)来确定被测试的值是否确实是一个字母。如果遇到大写字母,则计数会增加,从而允许代码遍历整个字符串。我们使用逻辑“&&”运算符在最终 if 函数中完成两个逻辑检查。

    如何改进: 一旦计数增加到 0 以上,您可以通过返回 true 来改进此代码,但如果您愿意,我会留给您。

    编辑:将第二个 If 语句移到 for 循环中,以便在满足条件后立即返回 true,而不必在检查之前遍历整个字符串。

    function isUpper(str) {
      let count = 0;
    
      for (let i = 0; i < str.length; i++) {
        if (/[a-zA-Z]/.test(str.charAt(i)) && str.charAt(i) == str.charAt(i).toUpperCase()) {
          count += 1;
        }
    
        if (count > 0) {
          return true;
        }
      }
    
      return false;
    
    }
    

    如果这有帮助,请告诉我!

    【讨论】:

    • 我对您的代码有一个小问题:对于诸如 "THIS IS UPPER" 这样的字符串会发生什么?因为从我所看到的情况来看,即使存在小写字符,它仍然会返回 true。检查小写字符会更容易,然后在返回中翻转真/假的位置。
    • 从我如何解释发帖者的问题来看,您的示例应该返回 true。如果我读到帖子中的倒数第二句“如果字符串中有大写字符,我希望它返回 true”,我的解释是因为只有一个字符需要大写才能返回 true,而不是整个字符串。
    • 啊,我没有看到,但是你可以编辑你的 for 语句,这样当它找到一个大写字符时它不会遍历整个字符串。即使满足查找大写字符的条件,您也可以简单地使用 return true 而不是遍历字符串。
    • 是的,这是真的,我在我的代码中提到了可以做到的。可以将第二个 if 语句放在第一个 if 语句之后的 for 循环中,然后在考虑每个字母后检查计数是否增加。我只是想避免在不解释发生了什么的情况下做太多事情,例如整个事情可以用 2 行 Regex 来实现,但我不确定这个人对此了解多少。我将编辑代码以显示这一点。感谢您的建议!
    • 这只是哲学问题,但老实说,如果 OP 不了解正则表达式,我们作为更高级的开发人员/工程师的工作就是向他们介绍它。如果我们不向他们展示他们还不知道的事情(尤其是与解决他们的问题直接相关的事情),那么我们就没有帮助他们成长。
    猜你喜欢
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    相关资源
    最近更新 更多