【问题标题】:Is it okay to use for in loop on a string?可以在字符串上使用 for in 循环吗?
【发布时间】:2019-09-26 20:37:50
【问题描述】:

只是想知道在字符串上使用 for in 循环是否可以接受。不确定是否会有奇怪的结果或不好的做法,但我的解决方案至少在这个例子中有效。

编码练习题。另外,如果有人有办法改进我的解决方案,我愿意接受建议。

function firstNonRepeatingLetter(str) {
  const lowerStr = str.toLowerCase();

  for (let char in lowerStr) {
    if (lowerStr.lastIndexOf(lowerStr[char]) === parseInt(char) && 
    lowerStr.indexOf(lowerStr[char]) === parseInt(char)) {
      return str[char];
    }
  }

  return "";
}

编写一个名为first_non_repeating_letter 的函数,该函数接受string 输入,并返回字符串中不重复的第一个字符。

例子:

firstNonRepeatingLetter('a') => 'a'
firstNonRepeatingLetter('stress') => 't'
firstNonRepeatingLetter('sTreSS') => 'T'

【问题讨论】:

标签: javascript for-loop indexof for-in-loop lastindexof


【解决方案1】:

当您的代码正常工作时,我建议使用索引来迭代字符串的字符。

但是您的方法通过使用indexOflastIndexOf 对字符串进行了多次迭代。这可以通过使用存储最后找到的字符索引的循环来更改。

在另一个循环中,将实际索引与存储的相同字符的索引进行比较,如果相等则返回。

function firstNonRepeatingLetter(str) {
    var lowerStr = str.toLowerCase(),
        hash = {},
        i;

    for (i = 0; i < lowerStr.length; i++)
        hash[lowerStr[i]] = i;

    for (i = 0; i < lowerStr.length; i++)
        if (hash[lowerStr[i]] === i)
            return str[i];

    return "";
}

console.log(firstNonRepeatingLetter('a'));      // a
console.log(firstNonRepeatingLetter('stress')); // t
console.log(firstNonRepeatingLetter('sTreSS')); // T

【讨论】:

  • 你拼错了indesOf
  • @Noob,你也是。
【解决方案2】:

要回答这个问题,是的,您可以将for..in 与字符串一起使用。事实上,在大多数情况下,您不应该这样做。

for(i in X) 这样工作:

  • 如果 X 不是对象,则将其转换为相应的包装器(将数字转换为 Number,将字符串转换为 String
  • 对于 X 的每个“可枚举属性”,将其名称分配给 i 并运行循环体

因此字符串被转换为String 对象,正如您在控制台中看到的那样,它们就像数组一样:它们具有从 0 到长度 - 1 的数字属性,并且每个属性都包含相应的字符:

也就是说,是的,上述逻辑适用于字符串。

但是,如果您只想逐个字符地迭代字符串,还有一种更直接的方法可以做到这一点:for..of 循环。

for(a of X) 从 X(可以是字符串、数组或任何“可迭代”对象)中挑选每个 元素(不是属性)并将其分配给“a”。使用for..of,您的代码可以这样重构:

function firstNonRepeatingLetter(str) {
    const lowerStr = str.toLowerCase();

    for (let char of lowerStr) {
        if (lowerStr.lastIndexOf(char) === lowerStr.indexOf(char))
            return char;
    }

    return "";
}

【讨论】:

  • 谢谢!!我开始使用 for of 但因为我想要他们的索引,所以我决定改用 for in。感谢您的回复!
【解决方案3】:

使用javascript maps 的算法方法: 是的,将for loops 与字符串一起使用非常好。

const fn = (str) => {
  res = [];
  var ch = new Map();
  for(var i = 0; i<str.length; i++) {
    if(ch.has(str[i])) {
      var val = ch.get(str[i])
      val += 1
      ch.set(str[i],val)
    } else {
      ch.set(str[i], 1)
    }
  }
  ch.forEach((val, key) => {
    if(val == 1) {
      res.push(key)
    }
  })
  return res[0]
}

console.log(fn('abcdeabcdef'))

【讨论】:

    【解决方案4】:

    使用两个数组怎么样?首先,您可以使用split 创建一个数组,也可以创建一个反转数组。

    const origin = str.split('');
    const reverse = [...origin].reverse();
    

    然后,您可以使用filter

    const nonRepeats = origin.filter((ele, index) => ele !== reverse[index]);
    return nonRepeats[0];
    

    【讨论】:

    • 很棒的解决方案,谢谢!这些是我正在努力争取的解决方案
    【解决方案5】:

    为了回答标题中的问题,for..in 语句用于迭代可枚举的对象属性(包括原型链中的成员)。虽然它“适用”可迭代类型,但通常建议不要将其用作迭代类数组结构的方法,因为当您通常只查看数字索引时,它可能会产生意想不到的结果。 p>

    例如,假设您稍后使用 polyfill 功能或以其他方式修改字符串原型。

    String.prototype.polyfill = () => {}
    for(const prop in 'abc')
        console.log(prop)

    编辑:哦,快。看起来我们两个人同时到达那里。我还会注意到,正则表达式擅长解决这类问题。 regex 101

    const firstNonRepeatingLetter = str => 
        (str && /(.)(?!.*?\1)/i.exec(str)[0]) || ''
        
    ;[
        'a',
        'stress',
        'sTreSS'
    ]
        .forEach(
            str => console.log(firstNonRepeatingLetter(str))
        )

    【讨论】:

      【解决方案6】:

      我认为,一旦您在找到此任务的网站上解决了答案,它就会向您显示其他答案,因此您可以看到其他一些方法。

      回到问题 - 您可以通过.split() 方法将字符串转换为数组。 Array 提供了许多有用的方法,例如.filter().map() 等,可以用来代替for 循环。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-11
        • 1970-01-01
        • 1970-01-01
        • 2014-03-05
        • 1970-01-01
        • 2018-06-13
        • 2017-12-24
        相关资源
        最近更新 更多