【问题标题】:JavaScript "firstNonRepeatingLetter" function returning undefined instead of a character?JavaScript“firstNonRepeatingLetter”函数返回未定义而不是字符?
【发布时间】:2018-07-19 16:53:16
【问题描述】:

这里是问题陈述:

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

例如,如果输入 'stress',函数应该返回 't',因为字母 t 在字符串中只出现一次,并且在字符串中首先出现。

作为一个额外的挑战,大写和小写字母被认为是相同的字符,但函数应该返回首字母的正确大小写。例如,输入“sTreSS”应返回“T”。

下面是我的代码,它返回未定义。我无法捕捉到错误。

function firstNonRepeatingLetter(s) {
  var x = s.replace(" ", "");
  for (var i = 0; i < x.length; i++) {
    if (x.charCodeAt(i) < 96) {
     
      var y = x.replace(x[i], "");
      var z = String.fromCharCode(x.charCodeAt(i) + 32);
      if (y.indexOf(x[0]) > -1 || y.indexOf(z) > -1) {
        continue;
      } else {
        var m = x[i];
      }
      return m;
    } else if (x.charCodeAt(i) > 96) {
      
      var y = x.replace(x[i], "");
      var z = String.fromCharCode(x.charCodeAt(i) - 32);
      if (y.indexOf(x[0]) > -1 || y.indexOf(z) > -1) {
        continue;
      } else {
        var m = x[i];
      }
      return m;
    }
  }
}

【问题讨论】:

  • 你有一个 ifelse if... 但没有 else ...因此,如果您不满足前 2 个 if 条件,您将返回 undefined。
  • 请尝试使用浏览器的debugging capabilities。您已使用 console.log 记录结果。为什么不在你的函数中记录相关变量,或者使用debugger
  • @Xufox 啊,是的,我跳得太早了……再看一遍

标签: javascript arrays string undefined


【解决方案1】:

您的条件y.indexOf(x[0]) &gt; -1 不正确。您不需要比较 first 字符,而是 ith 字符。将它们都替换为y.indexOf(x[i]) &gt; -1


一些提示:

  • 避免使用单字母变量名。它们使调试和理解代码变得异常困难。
  • 块内的var 声明,如forif 等,没有任何用处。您已重新声明 var m 两次。这只会增加混乱。
  • .replace(" ", "") 仅删除第一个空格,即使您可能打算删除所有空格。要么使用正则表达式(也可用于添加更多案例,或​​将输入限制为特定字符),要么使用replaceAll(注意浏览器兼容性和提案状态)。使用正则表达式可能看起来像.replace(/\s/g, "") 来删除所有空格,或.replace(/[^a-z]/gi, "") 来删除任何非拉丁字母。
  • 不要在 charcode 中添加或减去 32,只需使用 .toUpperCase.toLowerCase
  • 同样,比较 小于或大于 96 的字符代码不会处理具有此精确字符代码的字符,即 ` 字符。相反,请考虑将整个字符串转换为大写或小写,而不是分别处理这两种情况。
  • 最后,根据分配是否允许这样做,考虑使用ObjectArray 方法。

这是在 ECMAScript 2015+ 中编写函数的两种方式:

const getFirstUniqueLetter = (string) => {
  string = [...string.replace(/\s/g, "")];

  const {
    map,
    unique
  } = string.reduce((result, character) => {
      result.map[character.toLowerCase()] = (result.map[character.toLowerCase()] || 0) + 1;

      if(!result.unique.includes(character)){
        result.unique.push(character);
      }

      return result;
    }, {
      map: {},
      unique: []
    });

  // You can add the `|| ""` in the next line to get a default output of the empty string, if no character is unique. Otherwise, `undefined` is returned.
  return unique.find((character) => map[character.toLowerCase()] === 1) /* || "" */;
};
const getFirstUniqueLetter = (string) => {
  string = string.replace(/\s/g, "");

  // You can add the `|| ""` in the next line to get a default output of the empty string, if no character is unique. Otherwise, `undefined` is returned.
  return [...string].find((character) => string.match(new RegExp(character, "gi")).length === 1) /* || "" */;
};

【讨论】:

  • 我认为通过使用替换我正在“删除”给定字符串的第一个字符。这就是为什么我在每次迭代中都采用“0”索引。
  • @Xufox 你已经用replace 的提示补充了你的答案,只替换了第一次出现的模式。事实上,这个练习似乎并不适合所有字符重复的情况。
  • @collapsar 老实说,我不明白你的意思。 .replace(" ", "") 似乎应该删除所有空格,但它没有这样做。
  • @Xufox MDN 上的措辞不是特别清楚,因为他们主要考虑第一个参数是 RegExp 的情况,但调用 .replace 需要替换第一个模式/字符串仅发生。
  • @Xufox:然而,在最新的ECMA specs 中,行为是明确定义的(虽然很难理解)
【解决方案2】:

这并不能解决您编写的代码,但我想我会提供一种替代方法。

    function firstNonRepeatingLetter(s){
      var allCharacters = s.split('');
      var character;
      var characterMap = {};
      //get all character counts
      for(var i=0;i<allCharacters.length;i++){
        character = allCharacters[i];
        if(typeof(characterMap[character]) == 'undefined'){
          characterMap[character] = 0;
        }
        characterMap[character]++;
      }
      //remove any duplicates
      for(var c in characterMap){
        if(characterMap[c] > 1){
          delete characterMap[c];
        }
      }
      //find the first character in your string that is *still* in the map
      for(var i=0;i<allCharacters.length;i++){
        character = allCharacters[i];
        if(typeof(characterMap[character]) != 'undefined'){
          return character;
        }
      }
      //all characters in the string were duplicated (e.g. "ABBA")
      return 'No non repeating letters';
    }
    
    console.log(firstNonRepeatingLetter("stress"));
    console.log(firstNonRepeatingLetter("doodle"));
    console.log(firstNonRepeatingLetter("abba"));
    console.log(firstNonRepeatingLetter("supercalifragilisticexpialidocious"));

【讨论】:

    猜你喜欢
    • 2018-05-08
    • 1970-01-01
    • 2019-05-17
    • 2021-06-04
    • 2021-09-11
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 2020-03-16
    相关资源
    最近更新 更多