JavaScript“ firstNonRepeatingLetter”函数返回未定义的字符而不是字符?

时间:2018-07-19 16:53:16

标签: javascript arrays string undefined

以下是问题说明:

编写一个名为firstNonRepeatingLetter†的函数,该函数接受一个字符串输入,并返回该字符串中任何地方都没有重复的第一个字符。

例如,如果给定输入“重音”,则函数应返回“ 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;
    }
  }
}

2 个答案:

答案 0 :(得分:1)

您的条件y.indexOf(x[0]) > -1不正确。您不需要比较第一个字符,而只需比较第i个字符。将它们都替换为y.indexOf(x[i]) > -1


一些提示:

  • 避免使用单字母变量名称。它们使调试和理解您的代码变得异常困难。
  • 块内的
  • var声明,例如forif等,没有任何用处。您已两次{@ {1}}重新声明。这只会增加混乱。
  • var m仅删除第一个空格,即使您可能想删除所有空格。要么使用正则表达式(也可以用于添加更多的大小写,或者将输入内容限制为特定字符),或者使用replaceAll(请注意浏览器的兼容性和投标状态)。使用正则表达式看起来像.replace(" ", "")删除所有空格,或.replace(/\s/g, "")删除所有不是拉丁字母的东西。
  • 不要使用字符代码添加或减去.replace(/[^a-z]/gi, ""),而只需使用.toUpperCase.toLowerCase
  • 同样地,比较小于或大于 32的字符代码将不会使用具有此确切字符的字符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) /* || "" */;
};

答案 1 :(得分:0)

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

    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"));