如何在Javascript中获取下一个字母?

43

我正在构建一个自动完成程序,它会从CouchDB视图中搜索。

我需要能够获取输入字符串的最后一个字符,并将最后一个字符替换为英文字母表中的下一个字母。(这里不需要i18n)

例如:

  • 输入字符串 = "b"
  • startkey = "b"
  • endkey = "c"

或者

  • 输入字符串 = "foo"
  • startkey = "foo"
  • endkey = "fop"

(如果你想知道,我在确保包括选项inclusive_end=false,以便这个额外的字符不会影响我的结果集)


问题

  • 是否有原生的Javascript函数可以获取字母表中的下一个字母?
  • 还是我需要自己动手写一个带有基础字符串(如"abc...xyz")和indexOf()的复杂函数?
7个回答

67
my_string.substring(0, my_string.length - 1)
      + String.fromCharCode(my_string.charCodeAt(my_string.length - 1) + 1)

10
但要注意 z/Z 的边缘情况: z +1 = { Z +1 = [ - Gabriele Petrioli
@ictoofay 谢谢,这立刻就起作用了。 @Gaby 感谢你提醒! - Dominic Barnes

33

// 这将返回大写字母 Z 的小写字母 a 和小写字母 z 的小写字母 a。

function nextLetter(s){
    return s.replace(/([a-zA-Z])[^a-zA-Z]*$/, function(a){
        var c= a.charCodeAt(0);
        switch(c){
            case 90: return 'A';
            case 122: return 'a';
            default: return String.fromCharCode(++c);
        }
    });
}

说实话,我原本期望的是类似于'a'++这样的速度,而不是整个正则表达式。 - Bojidar Stanchev

19

一种更全面的解决方案,根据 MS Excel 列编号的方式获取下一个字母... A B C ... Y Z AA AB ... AZ BA ... ZZ AAA

这适用于小写字母,但您也可以轻松地将其扩展到大写字母。

getNextKey = function(key) {
  if (key === 'Z' || key === 'z') {
    return String.fromCharCode(key.charCodeAt() - 25) + String.fromCharCode(key.charCodeAt() - 25); // AA or aa
  } else {
    var lastChar = key.slice(-1);
    var sub = key.slice(0, -1);
    if (lastChar === 'Z' || lastChar === 'z') {
      // If a string of length > 1 ends in Z/z,
      // increment the string (excluding the last Z/z) recursively,
      // and append A/a (depending on casing) to it
      return getNextKey(sub) + String.fromCharCode(lastChar.charCodeAt() - 25);
    } else {
      // (take till last char) append with (increment last char)
      return sub + String.fromCharCode(lastChar.charCodeAt() + 1);
    }
  }
  return key;
};

1
请注意,您也可以在 else{} 部分使用 key.substr(-1) 来获取最后一个字符,但这在 IE 的 JScript 中不起作用,因为 substr() 不接受负索引。不过我不确定新版 Edge 浏览器的支持情况... - kumarharsh
我发现IE11和Edge都支持在substr()中使用负索引...似乎IE10也是如此(通过在IE11中更改浏览器模式进行测试)。 - kumarharsh
这个函数没有按照你承诺的顺序返回键。你承诺的是 A B C ... Y Z AA AB ... AZ BA ... ZZ AAA,但实际上它返回的是 A B .. Y Z ZA ZB .. ZY ZZ ZZA ZZB .. ZZY ZZZ ZZZA ZZZB ... - Wyck
@Wyck - 感谢您指出这个问题,脚本确实有误。我已经修复了脚本。虽然我认为您的评论有点不对:该函数输出的是 AA AB ... AZ A[,但至少从我的测试结果来看,它正确地输出了 ZZA....ZZZ AAAA - kumarharsh

7

这里有一个函数,它做相同的事情(除了只针对大写字母,但很容易改变),但仅使用一次slice并且是迭代的而不是递归的。在快速基准测试中,它大约快4倍(只有在您确实大量使用它时才相关)。

function nextString(str) {
  if (! str)
    return 'A'  // return 'A' if str is empty or null

  let tail = ''
  let i = str.length -1
  let char = str[i]
  // find the index of the first character from the right that is not a 'Z'
  while (char === 'Z' && i > 0) {
    i--
    char = str[i]
    tail = 'A' + tail   // tail contains a string of 'A'
  }
  if (char === 'Z') // the string was made only of 'Z'
    return 'AA' + tail
  // increment the character that was not a 'Z'
  return str.slice(0, i) + String.fromCharCode(char.charCodeAt(0) + 1) + tail
}

4

仅解释Bipul Yadav编写的代码的主要部分(由于声誉不足,目前无法进行评论)。不考虑循环,以字符“a”为例:

"a".charCodeAt(0) = 97,因此 "a".charCodeAt(0) + 1 = 98String.fromCharCode(98) = "b"...因此下面的函数针对任何字母都将返回字母表中的下一个字母:

function nextLetterInAlphabet(letter) {
  if (letter == "z") {
    return "a";
  } else if (letter == "Z") {
    return "A";
  } else {
    return String.fromCharCode(letter.charCodeAt(0) + 1);
  }
}

1
var input = "Hello";
var result = ""
for(var i=0;i<input.length;i++)
{
  var curr = String.fromCharCode(input.charCodeAt(i)+1);
  result = result +curr;
}
console.log(result);

1
请添加一些解释,说明为什么这个答案有用以及它是如何工作的。仅有代码的答案价值较低,特别是从长远来看。假设读者不像你一样了解这个问题,因此可能无法理解你的代码。 - TylerH

0

我知道原问题是关于将字符串的最后一个字母向前移动到下一个字母。但我对这个问题更感兴趣的是改变字符串中的所有字母,然后能够撤消这种更改。因此,我采用了Bipul Yadav编写的代码,并添加了一些代码。以下代码接受一系列字母,将它们递增到下一个字母并保持大小写(并使Zz变为Aa),然后将它们回滚到上一个字母(并允许Aa返回到Zz)。

var inputValue = "AaZzHello";
console.log( "starting value=[" + inputValue + "]" );

var resultFromIncrementing = ""
for( var i = 0; i < inputValue.length; i++ ) {
    var curr = String.fromCharCode( inputValue.charCodeAt(i) + 1 );
    if( curr == "[" ) curr = "A";
    if( curr == "{" ) curr = "a";
    resultFromIncrementing = resultFromIncrementing + curr;
}
console.log( "resultFromIncrementing=[" + resultFromIncrementing + "]" );

inputValue = resultFromIncrementing;
var resultFromDecrementing = "";
for( var i2 = 0; i2 < inputValue.length; i2++ ) {
    var curr2 = String.fromCharCode( inputValue.charCodeAt(i2) - 1 );
    if( curr2 == "@" ) curr2 = "Z";
    if( curr2 == "`" ) curr2 = "z";
    resultFromDecrementing = resultFromDecrementing + curr2;
}
console.log( "resultFromDecrementing=[" + resultFromDecrementing + "]" );

这个的输出是:

starting value=[AaZzHello]
resultFromIncrementing=[BbAaIfmmp]
resultFromDecrementing=[AaZzHello]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接