Qual é o método que pode ser usado para incrementar letras?


98

Alguém conhece uma biblioteca Javascript (por exemplo, sublinhado, jQuery, MooTools, etc.) que oferece um método de incrementar uma letra?

Eu gostaria de ser capaz de fazer algo como:

"a"++; // would return "b"

Não tenho certeza se a sintaxe que você está procurando é possível, mas a operação é possível por meio de métodos.
anson

Qual é o aplicativo?
valentinas

Respostas:


177

Solução simples e direta

function nextChar(c) {
    return String.fromCharCode(c.charCodeAt(0) + 1);
}
nextChar('a');

Como outros observaram, a desvantagem é que ele pode não lidar com casos como a letra 'z' como esperado. Mas depende do que você quer com isso. A solução acima retornará '{' para o caractere após 'z', e este é o caractere após 'z' em ASCII, portanto, pode ser o resultado que você está procurando, dependendo de qual é o seu caso de uso.


Gerador de string único

(Atualizado em 09/05/2019)

Como essa resposta recebeu tanta visibilidade, decidi expandi-la um pouco além do escopo da pergunta original para ajudar potencialmente as pessoas que estão tropeçando nisso do Google.

Descobri que o que geralmente quero é algo que gere strings sequenciais e exclusivas em um determinado conjunto de caracteres (como usar apenas letras), então atualizei esta resposta para incluir uma classe que fará isso aqui:

class StringIdGenerator {
  constructor(chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
    this._chars = chars;
    this._nextId = [0];
  }

  next() {
    const r = [];
    for (const char of this._nextId) {
      r.unshift(this._chars[char]);
    }
    this._increment();
    return r.join('');
  }

  _increment() {
    for (let i = 0; i < this._nextId.length; i++) {
      const val = ++this._nextId[i];
      if (val >= this._chars.length) {
        this._nextId[i] = 0;
      } else {
        return;
      }
    }
    this._nextId.push(0);
  }

  *[Symbol.iterator]() {
    while (true) {
      yield this.next();
    }
  }
}

Uso:

const ids = new StringIdGenerator();

ids.next(); // 'a'
ids.next(); // 'b'
ids.next(); // 'c'

// ...
ids.next(); // 'z'
ids.next(); // 'A'
ids.next(); // 'B'

// ...
ids.next(); // 'Z'
ids.next(); // 'aa'
ids.next(); // 'ab'
ids.next(); // 'ac'

Solução simples, mas não trata a ocorrência de 'z' ou 'Z'.
Trent de

3
tipo de buzzkill que irá entrar em caracteres especiais como /
Daniel Thompson,

Exatamente o que eu estava procurando enquanto tentava selecionar caracteres Unicode não exibidos para uma fonte IBM Code Page 437 da velha escola. Você literalmente me economizou horas de digitação de caracteres.
LeftOnTheMoon

1
Daniel Thompson, esta solução fornece informações mais do que suficientes, você mesmo pode lidar com os casos difíceis. Afinal, este é um site de "ajuda mútua", não um site de trabalho gratuito.
Bojidar Stanchev

Levei um tempo para descobrir como fazer o personagem inicial ser um argumento. Acabei usando ._nextId = [chars.split (''). FindIndex (x => x == start)]; Ou comece + 1 se quiser começar 1 a mais do que o que você passou.
JohnDavid

49

JavaScript simples deve resolver o problema:

String.fromCharCode('A'.charCodeAt() + 1) // Returns B

1
Pure Charm, qualquer sugestão para evitar espaços em branco e caracteres especiais. coderByte tem uma pergunta sobre isso
sg28

22

E se a letra fornecida for z? Aqui está uma solução melhor. Ele vai A, B, C ... X, Y, Z, AA, AB, ... etc. Basicamente, ele incrementa letras como os IDs de coluna de uma planilha do Excel.

nextChar ('yz'); // retorna "ZA"

    function nextChar(c) {
        var u = c.toUpperCase();
        if (same(u,'Z')){
            var txt = '';
            var i = u.length;
            while (i--) {
                txt += 'A';
            }
            return (txt+'A');
        } else {
            var p = "";
            var q = "";
            if(u.length > 1){
                p = u.substring(0, u.length - 1);
                q = String.fromCharCode(p.slice(-1).charCodeAt(0));
            }
            var l = u.slice(-1).charCodeAt(0);
            var z = nextLetter(l);
            if(z==='A'){
                return p.slice(0,-1) + nextLetter(q.slice(-1).charCodeAt(0)) + z;
            } else {
                return p + z;
            }
        }
    }
    
    function nextLetter(l){
        if(l<90){
            return String.fromCharCode(l + 1);
        }
        else{
            return 'A';
        }
    }
    
    function same(str,char){
        var i = str.length;
        while (i--) {
            if (str[i]!==char){
                return false;
            }
        }
        return true;
    }

// below is simply for the html sample interface and is unrelated to the javascript solution

var btn = document.getElementById('btn');
var entry = document.getElementById('entry');
var node = document.createElement("div");
node.id = "node";

btn.addEventListener("click", function(){
  node.innerHTML = '';
  var textnode = document.createTextNode(nextChar(entry.value));
  node.appendChild(textnode);
  document.body.appendChild(node);
});
<input id="entry" type="text"></input>
<button id="btn">enter</button>


Alterado if (same(u,'Z')){para if (u == 'Z'){e funciona perfeitamente, obrigado!
Sean Kendle de

Que bom que funcionou e obrigado pelo feedback. Talvez aquele erro inicial tenha ocorrido bcs a função intitulada same(str,char)não foi colada lá? Não sei.
Ronnie Royston

Deve ser o caso, same()é claramente uma função personalizada. Bem, ==funciona, e se eu quisesse ter certeza absoluta, poderia usar ===, mas testei e está bom. Obrigado novamente!
Sean Kendle de

se você digitar zz obterá triplo A, é um bug no código ??
Amr Ashraf

1
Acho que não? o que vem depois de zz? aaa certo? Eu não tenho o Excel instalado nesta máquina (para verificar novamente), mas parece certo para mim.
Ronnie Royston

5

Uma forma possível pode ser definida abaixo

function incrementString(value) {
  let carry = 1;
  let res = '';

  for (let i = value.length - 1; i >= 0; i--) {
    let char = value.toUpperCase().charCodeAt(i);

    char += carry;

    if (char > 90) {
      char = 65;
      carry = 1;
    } else {
      carry = 0;
    }

    res = String.fromCharCode(char) + res;

    if (!carry) {
      res = value.substring(0, i) + res;
      break;
    }
  }

  if (carry) {
    res = 'A' + res;
  }

  return res;
}

console.info(incrementString('AAA')); // will print AAB
console.info(incrementString('AZA')); // will print AZB
console.info(incrementString('AZ')); // will print BA
console.info(incrementString('AZZ')); // will print BAA
console.info(incrementString('ABZZ')); // will print ACAA
console.info(incrementString('BA')); // will print BB
console.info(incrementString('BAB')); // will print BAC

// ... and so on ...

4

Você pode tentar isso

console.log( 'a'.charCodeAt​(0))​

Primeiro, converta-o para um número Ascii .. Incremente-o .. e depois converta de Ascii para char ..

var nex = 'a'.charCodeAt(0);
console.log(nex)
$('#btn1').on('click', function() {
   var curr = String.fromCharCode(nex++)
   console.log(curr)
});

Verifique FIDDLE


1
Hmm. Precisa de mais jQuery.
Jasper

4

Eu precisei usar sequências de letras várias vezes e por isso fiz essa função com base nessa pergunta do SO. Espero que isso possa ajudar outras pessoas.

function charLoop(from, to, callback)
{
    var i = from.charCodeAt(0);
    var to = to.charCodeAt(0);
    for(;i<=to;i++) callback(String.fromCharCode(i));
}
  • de - carta inicial
  • para - última letra
  • callback (letra) - função a ser executada para cada letra na sequência

Como usá-lo:

charLoop("A", "K", function(char) {
    //char is one letter of the sequence
});

Veja esta demonstração de trabalho


3

Somando todas essas respostas:

// first code on page
String.prototype.nextChar = function(i) {
    var n = i | 1;
    return String.fromCharCode(this.charCodeAt(0) + n);
}

String.prototype.prevChar = function(i) {
    var n = i | 1;
    return String.fromCharCode(this.charCodeAt(0) - n);
}

Exemplo: http://jsfiddle.net/pitaj/3F5Qt/


2

Este funciona bem:

var nextLetter = letter => {
    let charCode = letter.charCodeAt(0);
    let isCapital = letter == letter.toUpperCase();

    if (isCapital == true) {
        return String.fromCharCode((charCode - 64) % 26 + 65)
    } else {
        return String.fromCharCode((charCode - 96) % 26 + 97)
    }
}

EXAMPLES

nextLetter("a"); // returns 'b'
nextLetter("z"); // returns 'a'
nextLetter("A"); // returns 'B'
nextLetter("Z"); // returns 'A'

1

Uma solução só para rir

function nextLetter(str) {
  const Alphabet = [
    // lower case 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",
    // upper case 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"
  ];

  const LetterArray = str.split("").map(letter => {
    if (Alphabet.includes(letter) === true) {
      return Alphabet[Alphabet.indexOf(letter) + 1];
    } else {
      return " ";
    }
  });

  const Assemble = () => LetterArray.join("").trim();
  return Assemble();
}


console.log(nextLetter("hello*3"));


0

Isso é muito antigo. Mas eu precisava dessa funcionalidade e nenhuma das soluções é ideal para meu caso de uso. Eu queria gerar a, b, c ... z, aa, ab ... zz, aaa .... Essa recursão simples faz o trabalho.

function nextChar(str) {
if (str.length == 0) {
    return 'a';
}
var charA = str.split('');
if (charA[charA.length - 1] === 'z') {
    return nextID(str.substring(0, charA.length - 1)) + 'a';
} else {
    return str.substring(0, charA.length - 1) +
        String.fromCharCode(charA[charA.length - 1].charCodeAt(0) + 1);
}
};

0

Faça uma função com {a: 'b', b: 'c', etc} em um encerramento: -

let nextChar = (s => (
    "abcdefghijklmopqrstuvwxyza".split('')
    .reduce((a,b)=> (s[a]=b, b)), // make the lookup
c=> s[c] // the function returned
))({}); // parameter s, starts empty

uso:-

nextChar('a')

Adicionando maiúsculas e dígitos: -

let nextCh = (
    (alphabeta, s) => (
        [alphabeta, alphabeta.toUpperCase(), "01234567890"]
            .forEach(chars => chars.split('')
               .reduce((a,b) => (s[a]=b, b))), 
        c=> s[c] 
    )
)("abcdefghijklmopqrstuvwxyza", {});

ps Em algumas versões de Javascript, você pode usar em [...chars]vez dechars.split('')



0

Aqui está uma variação do algoritmo rot13 que enviei em https://stackoverflow.com/a/28490254/881441 :

function rot1(s) {
  return s.replace(/[A-Z]/gi, c =>
    "BCDEFGHIJKLMNOPQRSTUVWXYZAbcdefghijklmnopqrstuvwxyza"[
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(c) ] )
}

O código de entrada na parte inferior e o codec pesquisado está na parte superior (ou seja, o código de saída é o mesmo que o código de entrada, mas deslocado em 1). A função muda apenas letras, ou seja, se qualquer outro caractere for passado, ele não será alterado por este codec.


0

function charLoop(from, to, callback) {
    var i = from.charCodeAt(0);
    var to = to.charCodeAt(0);
    for (; i <= to; i++) {
        callback(String.fromCharCode(i));
    }
}

var sequence = "";
charLoop("A", "Z", function (char) {
    sequence += char + " ";
});

sequence = sequence.trim();
sequence = sequence.split(" ");

var resseq = sequence;
var res = "";
var prevlet = "";
var nextlet = "";

for (b = 0; b < resseq.length; b++) {
    if (prevlet != "") {
        prevlet = resseq[b];
    }

    for (a = 0; a < sequence.length; a++) {
        for (j = 1; j < 100; j++) {
            if (prevlet == "") {
                prevlet = sequence[a];
                nextlet = sequence[a + 1];
                res += sequence[a] + sequence[a] + 0 + j + " ";
            }
            else {

                if (j < 10) {
                    res += prevlet + sequence[a] + 0 + j + " ";
                }
                else {
                    res += prevlet + sequence[a] + j + " ";
                }
            }
        }
    }
}

document.body.innerHTML = res;

1
Você pode querer explicar o que exatamente você fez aqui e como isso ajuda em vez de apenas ter um bloco de código, obrigado! - Talvez alguns comentários úteis no código?
Mark Davies

String.fromCharCode () retorna o código char da letra.
LokeshKumar

0

Com base no aumento e diminuição da resposta da parede @Nathan

// Albhabet auto increment and decrement
class StringIdGenerator {
    constructor(chars = '') {
      this._chars = chars;
    }

  next() {
    var u = this._chars.toUpperCase();
    if (this._same(u,'Z')){
        var txt = '';
        var i = u.length;
        while (i--) {
            txt += 'A';
        }
        this._chars = txt+'A';
        return (txt+'A');
    } else {
      var p = "";
      var q = "";
      if(u.length > 1){
          p = u.substring(0, u.length - 1);
          q = String.fromCharCode(p.slice(-1).charCodeAt(0));
      }
      var l = u.slice(-1).charCodeAt(0);
      var z = this._nextLetter(l);
      if(z==='A'){
        this._chars = p.slice(0,-1) + this._nextLetter(q.slice(-1).charCodeAt(0)) + z;
          return p.slice(0,-1) + this._nextLetter(q.slice(-1).charCodeAt(0)) + z;
      } else {
        this._chars = p+z;
          return p + z;
      }
    }
  }

  prev() {
    var u = this._chars.toUpperCase();
    console.log("u "+u)
    var l = u.slice(-1).charCodeAt(0);
    var z = this._nextLetter(l);
    var rl = u.slice(1)
    var y = (rl == "A") ? "Z" :this._prevLetter(rl.charCodeAt(0))
      var txt = '';
      var i = u.length;
      var j = this._chars
      var change = false
      while (i--) {
        if(change){
          if (u[u.length-1] == "A"){
            txt += this._prevLetter(u[i].charCodeAt(0))
          }else{
            txt += u[i]
          }
          
        }else{
          if (u[u.length-1] == "A"){
            txt += this._prevLetter(u[i].charCodeAt(0))
            change = true
          }else{
            change = true
            txt += this._prevLetter(u[i].charCodeAt(0))
          }
        }
      }
      if(u == "A" && txt == "Z"){
        this._chars = ''
      }else{
        this._chars = this._reverseString(txt);
      }
      console.log(this._chars)
      return (j);
  }
  _reverseString(str) {
      return str.split("").reverse().join("");
  }
  _nextLetter(l){
      if(l<90){
          return String.fromCharCode(l + 1);
      }
      else{
          return 'A';
      }
  }

  _prevLetter(l){
    if(l<=90){
      if(l == 65) l = 91
        return String.fromCharCode(l-1);
    }
    else{
        return 'A';
    }
  }
  _same(str,char){
      var i = str.length;
      while (i--) {
          if (str[i]!==char){
              return false;
          }
      }
      return true;
  }
    
}

Uso

const ids = new StringIdGenerator();

ids.next(); 
ids.prev();
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.