【问题标题】:Replace(), replacing a value not specifiedReplace(),替换一个未指定的值
【发布时间】:2019-05-15 04:55:00
【问题描述】:

我已经通过 FCC 学习 Javascript 6 周了,并决定花一周时间学习,并尝试使用方法来真正接近和舒适地在循环和语句中使用它们。只是在玩弦乐,我试图用“我喜欢丝绸”代替弦乐“我喜欢牛奶”。我的代码实现了这一点,我理解它,但我决定添加一个|| 运算符,结果让我感到困惑。如果我说if(x[i]=== 'm' || x[i] === 'I',它不会替换'I',而是替换'm' 如果我保留它在原始代码中的方式,它会生成字符串'I lise milk',即使从未提及'k' .怎么回事?

let x = 'Hello I like milk';
let y = '';

for(let i = 0; i < x.length; i++) {
    if(x[i] === 'm' || 'I') {
      y =  x.replace(x[i], 's' )
    }
}
console.log(y)

【问题讨论】:

  • 表达式x[i] === 'm' || 'I' 始终为真。它首先检查x[i]=== 'm',它可能是真或假,然后你有一个“或”运算符,然后是字符串文字'I'。该字符串文字始终为真,因此“或”运算符的计算结果为真,因此它始终为真。
  • 这可能有助于解释更多:developer.mozilla.org/en-US/docs/Glossary/truthy
  • 我完全理解这一点,前几天犯了那个错误并吸取了教训。我很困惑为什么它完全取代了'k'?正如您在我的问题中看到的那样,我已经尝试修复它,但它仍然没有替换“I”,而是替换了“m”,即使“I”在索引中排在第一位。

标签: javascript string methods logical-operators


【解决方案1】:

好的,有几个问题可以让你的代码变得有趣

  1. x[i] === 'm' || 'I' 总是正确的,因为 'I' 是正确的 - 如果不清楚,您可以使用 if ('I') { console.log('Merry Christmas') } 进行测试

  2. 你的循环产生一个新的字符串,每个循环都有一个替换,即它产生与没有循环相同的结果,并且

    y = x.replace(x[x.length - 1], 's')

  3. 替换将替换第一个匹配的字符 - 字符串中的最后一个字符是k,因此替换会将第一个匹配的k 更改为s

所以,你的代码的结果是

'Hello I lise milk'

希望这有助于解决问题!

顺便说一句,用s 替换所有ms 和Is 的最简单方法:

console.log(x.replace(/[mI]/g, 's'))

【讨论】:

  • 大部分都是这样,感谢您的解释,当我没有指定它时,我仍然不明白 k 是如何相关的,阅读 w3schools 文档,它没有提到“最后字符串的字符"
  • 这是因为x[i] === 'm' || 'I' 总是正确的!
  • 它只是没有登陆,我明白我的说法总是正确的,只是想不通为什么它专门取代了 K。我刚看了 Idiocracy,当我试图理解你的时候我能想到的一切'重新说的是“它有电解质”。我显然需要更多地了解这一点哈哈!
  • 好的,我喜欢学习如何成为更好的导师的挑战,所以我很乐意继续尝试不同的途径,直到清楚为止。由于我们知道谓词(if 语句)始终为真,因此我们可以将其从代码中删除。在循环的每次迭代中,先前计算的y 都会被丢弃。最后一次评估循环是在x 中的最后一个字母上,即k。有意义吗?
  • 是的,刚准备把我的电脑扔出窗外,我意识到事情就是这么简单。我犯了这个错误很多没有在循环中更新一个值,这就是事情开始变得令人沮丧的地方,这正是我决定休息一周的原因,开始学习和打破东西。
【解决方案2】:

因此,您基本上遇到了代码流动方式的问题。

让我们从问题一开始:为什么 m 被覆盖而不是 y?

所以基本上你有 var x 和 y 在你的循环中更新。

您的代码的工作方式基本上是:如果字母等于 m 或者我将其替换为 s。

但是,您将在这里遇到的问题是您永远不会存储已更新的值。因此,当它再次循环时,它将采用 x 的默认值(实际上并未更新)并将其写入 y。这将每次都覆盖该值。

我们可以通过简单地在循环内登录来演示这个。

let x = 'Hello I like milk';
let y = '';

for(let i = 0; i < x.length; i++) {
    if(x[i] === 'm' || x[i] === 'I') {
      y =  x.replace(x[i], 's' )
      console.log(y)
    }
}

所以如果你运行上面的,你会看到两行被输出。

  1. 你好像牛奶
  2. 你好我喜欢牛奶

m 是唯一被打印的,因为日志是在最终更新之后。

那么下一个问题:为什么要替换那个 k?

正如另一位评论所发布的,“我”总是诚实的。 Truthy 基本上意味着该值不为空、未定义、0 等。“I”具有一个值,这意味着它始终为真。

那么K被替换了吗?好吧,如果我们运行该代码,被检查和替换的最后一个字母是 k。 .replace 仅替换(默认情况下)它遇到的那个字母的第一个实例。在你的情况下,那个 K 是第一个看到的 K。

所以要修复它,不要检查“I”检查:x[i] === "I"

编辑:回答你关于为什么最后一个字母很重要的问题

所以最后一个字母在这里很重要,因为你基本上等同于:

if("I"){} 

所以上面的 sn-p,与你可能认为的实际意思相反,如果 this 有一个值,因为 I 是一个有效字符,它总是会报告 true。因此,对于您的循环,无论角色如何,实际上都在检查所有内容,因为 I 总是正确的。

这是一个简单的检查方法:

假设我有一个从 1 到 10 的整数数组。我有(伪代码):

如果数组值

按照您目前的想法,如果值小于 10,您会希望它停止打印,对吧?没有!再一次,因为我总是真实的,我们说 OR 的值 I(真实)所以我们总是会得到打印!

代码示例:

var x = [0, 1, 2, 3, 4 , 50, 60, 70, 80];

    for(var i = 0; i < x.length; i++){
       if(x[i] < 10 || "I") {
           console.log(x[i]);
       }
    }

看到了吗?一切都打印出来了!即使一半的值超过 10,它们仍在打印出来。为什么?因为“我”总是真实的!现在让我们对其进行一些编辑以使其检查更加严格:

let x = [0, 1, 2, 3, 4 , 50, 60, 70, 80];

    for(var i = 0; i < x.length; i++){
       if(x[i] < 10 || x[i] === "I") {
           console.log(x[i]);
       }
    }

看到了吗?好多了:)

【讨论】:

  • 谢谢你的回答帮了很大的忙,我还是不明白为什么字符串的最后一个字母在这里有任何相关性,但由于它在 2 个答案中提到,显然我在这里遗漏了一些东西。
  • @Adag89 添加了另一个编辑以帮助进一步解释,希望对您有所帮助。
  • 我才意识到我没有理解,哈哈!抱歉让事情变得如此简单如此复杂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2012-04-06
  • 2011-03-13
  • 2022-12-02
  • 2021-03-31
  • 2012-09-06
相关资源
最近更新 更多