【问题标题】:Capitalize the vowels元音大写
【发布时间】:2017-03-25 15:41:06
【问题描述】:

我一直在做一个挑战,我必须在 Javascript 中创建一个函数,它将字母位置改变一个并且元音必须大写,例如“f”变为“g”,“z”变为“A” " 和 "m" 转到 "O"。我做了很大一部分这些步骤,但我正在努力将元音大写。这是我的代码:

function LetterChanges(str) {
  var newString = [];

  for (var i = 0; i < str.length; i++) {
    if (str.charCodeAt(i) >= 97 && str.charCodeAt(i) <= 121) {
      newString.push(String.fromCharCode(str.charCodeAt(i) + 1));
    }
    // z to a
    else if (str.charCodeAt(i) === 122) {
      newString.push(String.fromCharCode(str.charCodeAt(i) - 57));
    } //spaces
    else if (str.charCodeAt(i) === 32) {
      newString.push(String.fromCharCode(32));
    } else {
      newString.push(String.fromCharCode(str.charCodeAt(i)));
    }
  }

  return newString.join("");
}

console.log(LetterChanges("fanzd times!"));

【问题讨论】:

  • 为什么“m”变成“O”?不应该是“n”
  • 元音大写的哪一部分你在纠结?测试一个字母是不是元音,还是改变大小写?
  • 小写和大写字母的ascii码差为32,如a=>97, A=>65, b=>98, B=>66
  • 考虑接受有帮助的答案。通过接受一个答案,您向未来的读者表明这是一个正确的答案。要接受答案,请单击最佳答案旁边的空心复选标记,这样做会提高您的声誉并提供更多功能,请参阅reputation faq 更多详细信息,请参阅this page

标签: javascript arrays


【解决方案1】:

你并不孤单。很多人在遇到这样的问题时,首先会编写涉及字符代码、if 语句等的复杂逻辑。通常有一个更简单的方法:写下“源”和“目标”字母,然后编写两行代码来翻译输入它们之间。如果结果不符合您的预期,只需编辑目标字母表即可。

src = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
dst = 'bcdEfghIjklmnOpqrstUvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZA'

str = 'whatever!'
out = ''

for (c of str)
  out += dst[src.indexOf(c)] || c
  
console.log(out)
  

【讨论】:

  • 这是最好的,简单的代码,简单易懂,很难出错!
  • 是的,都是关于“字母表”的。原题讲了一些字母。有数以万计的字母。定义字母表会导致最简单、最可验证的解决方案。
【解决方案2】:

您可以运行 string.replace 并检查元音,如下所示;

function LetterChanges(str) {
  var newString = "";

  for (var i = 0; i < str.length; i++) {
    if (str.charCodeAt(i) >= 97 && str.charCodeAt(i) <= 121) {
      newString += String.fromCharCode(str.charCodeAt(i) + 1);
    }
    // z to a
    else if (str.charCodeAt(i) === 122) {
      newString += String.fromCharCode(str.charCodeAt(i) - 57);
    } //spaces
    else if (str.charCodeAt(i) === 32) {
      newString += String.fromCharCode(32);
    } else {
      newString += String.fromCharCode(str.charCodeAt(i));
    }
  }


  return newString.replace(/[aeiou]/gi, function(a){return a.charAt().toUpperCase()});
}

console.log(LetterChanges("fanzd times!"));

【讨论】:

    【解决方案3】:

    字符范围/代码与字典映射

    处理字符范围非常令人困惑,如果不查找 ascii 字符代码引用,97 &lt;= str.charCodeAt(i) &lt;= 121 几乎没有意义。更简洁的解决方案是构建一个字典,将字母映射到您想要的结果,例如{a: 'b', b: 'c', c: 'd', d: 'E', ...},它可以非常高效和干净地构建 - 这更容易调试,并且更具可读性/可理解性。

    建议的解决方案

    作为我对另一个问题 (Replace letters in string with a dictionary array set in Javascript) 的答案之一的修改版本,如果您使用的是 Node.js、JS 预编译器或不关心旧浏览器,则可以改为执行类似的操作并且可以使用 ES6:

    class LetterChanges {
        constructor() {
            const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
    
            this.encryptionKey = {};
    
            // build encryptionKey = {a: 'b', b: 'c', c: 'd', d: 'E', ...}
            for (let i=0; i<alphabet.length; i+=1) {
                const j = (i + 1) % alphabet.length;
    
                this.encryptionKey[alphabet[i]] = alphabet[j].replace(/[aeiou]/, match => match.toUpperCase());
            }
        }
    
        /**
         * Encrypt some plaintext
         * @param plaintext
         */
        encrypt(plaintext) {
            return plaintext.split('').map(letter => this.encryptionKey[letter] || letter).join('');
        }
    }
    
    const cipher = new LetterChanges();
    const plaintext = 'fanzd times!';
    const encoded = cipher.encrypt(plaintext);
    
    console.log(plaintext, encoded);  // "fanzd times!", "gbOAE Ujnft!"
    

    【讨论】:

      【解决方案4】:

      据我所知,没有聪明的算法方法可以判断一个字母是否是元音。因此,对于检查,您将需要使用一个普通的旧 indexOf ['a', 'e', 'i', 'o', 'u'].indexOf(c) !== -1

      我会将它放在循环中的其他转换之后,作为位置 i 的 newString 上的单独条件,如果它是元音,则执行转换。

      【讨论】:

      • 无需使用.toLowerCase。如果不是小写,则无需大写。
      • 由于字符串只是 JS 中的一个字符数组,因此您的检查可以简化为 "aeiou".indexOf(c) &gt; -1
      • 绝对。我删除了它。
      • “y”呢?
      • 只是有时?
      【解决方案5】:

      对于特殊情况“z”转到“A”,您已经通过从小写转换为大写来正确处理它。您可以以相同的方式处理其他元音,通过专门搜索前面字符的 ASCII 值并将它们更改为大写元音的正确 ASCII 代码。当然,您需要在一般情况“a - z”之前进行区分才能使代码正常工作;-)

      底线:if-else 级联不必具有互斥条件 - 第一场比赛获胜,其他比赛因“else”而被跳过。

      此外,“32”和“所有其他”的情况相同,因此您可以将它们组合起来。如果你不改变字符,你可以使用str[i] - 不需要转换。

      【讨论】:

        猜你喜欢
        • 2020-10-30
        • 2019-01-01
        • 1970-01-01
        • 2011-07-21
        • 2014-02-13
        • 2018-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多