¿Cuál es un método que se puede utilizar para incrementar letras?


98

¿Alguien sabe de una biblioteca Javascript (por ejemplo, subrayado, jQuery, MooTools, etc.) que ofrece un método para incrementar una letra?

Me gustaría poder hacer algo como:

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

No estoy seguro de que la sintaxis que está buscando sea posible, pero la operación es posible a través de métodos.
Anson

Cual es la aplicacion?
Valentinas

Respuestas:


177

Solución simple y directa

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

Como han señalado otros, el inconveniente es que puede no manejar casos como la letra 'z' como se esperaba. Pero depende de lo que quieras de él. La solución anterior devolverá '{' para el carácter después de 'z', y este es el carácter después de 'z' en ASCII, por lo que podría ser el resultado que está buscando dependiendo de cuál sea su caso de uso.


Generador de cuerdas único

(Actualizado 09/05/2019)

Dado que esta respuesta ha recibido tanta visibilidad, he decidido expandirla un poco más allá del alcance de la pregunta original para ayudar potencialmente a las personas que se encuentran con esto de Google.

Encuentro que lo que a menudo quiero es algo que genere cadenas secuenciales y únicas en un determinado conjunto de caracteres (como usar solo letras), así que actualicé esta respuesta para incluir una clase que hará eso aquí:

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'

Solución simple, pero no maneja la aparición de 'z' o 'Z'.
Trent

3
una especie de buzzkill que incluirá caracteres especiales como /
Daniel Thompson

Exactamente lo que estaba buscando mientras intentaba revisar y seleccionar caracteres Unicode que no se muestran en una fuente IBM Code Page 437 de la vieja escuela. Literalmente me ahorraste horas escribiendo caracteres.
LeftOnTheMoon

1
Daniel Thompson esta solución proporciona información más que suficiente, usted mismo puede manejar los casos de esquina. Después de todo, este es un sitio web de "ayuda mutua", no hago mi trabajo gratis.
Bojidar Stanchev

Me tomó un tiempo descubrir cómo hacer que el personaje inicial fuera un argumento. Terminé usando ._nextId = [chars.split (''). FindIndex (x => x == start)]; O inicie +1 si desea que comience 1 más de lo que ingresó.
JohnDavid

49

JavaScript simple debería hacer el truco:

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

1
Pure Charm, cualquier sugerencia para evitar espacios en blanco y caracteres especiales. coderByte tiene una pregunta sobre esto
sg28

22

¿Y si la letra dada es z? Aquí tienes una mejor solución. Va A, B, C ... X, Y, Z, AA, AB, ... etc. Básicamente, incrementa letras como los ID de columna de una hoja de cálculo de Excel.

nextChar ('yz'); // devuelve "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>


Cambiado if (same(u,'Z')){a if (u == 'Z'){y funciona perfectamente, gracias!
Sean Kendle

Me alegro de que haya funcionado y gracias por los comentarios. ¿Quizás ese error inicial fue porque la función titulada same(str,char)no se pegó allí? No se.
Ronnie Royston

Tiene que ser el caso, same()es claramente una función personalizada. Bueno, ==funciona, y si quisiera estar súper seguro, podría usarlo ===, pero lo probé y está bien. ¡Gracias de nuevo!
Sean Kendle

si escribe zz obtendrá triple A ¿es un error en el código?
Amr Ashraf

1
¿No lo creo? ¿Qué viene después de zz? aaa ¿verdad? No tengo Excel instalado en esta máquina (para verificar) pero me suena bien.
Ronnie Royston

5

Una forma posible podría ser la que se define a continuación

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

Puedes probar esto

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

Primero conviértalo a número Ascii .. Increméntelo .. luego convierta de Ascii a char ..

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

Verificar FIDDLE


1
Hmm. Necesita más jQuery.
Jasper

4

Necesitaba usar secuencias de letras varias veces, por lo que hice esta función en función de esta pregunta SO. Espero que esto pueda ayudar a otros.

function charLoop(from, to, callback)
{
    var i = from.charCodeAt(0);
    var to = to.charCodeAt(0);
    for(;i<=to;i++) callback(String.fromCharCode(i));
}
  • desde - letra de inicio
  • a - última letra
  • callback (letra) - función a ejecutar para cada letra en la secuencia

Cómo usarlo:

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

Ver esta demostración funcional


3

Agregando todas estas respuestas:

// 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);
}

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


2

Este funciona bien:

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

Una solución solo para reír

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

Esto es muy antiguo. Pero necesitaba esta funcionalidad y ninguna de las soluciones es óptima para mi caso de uso. Quería generar a, b, c ... z, aa, ab ... zz, aaa .... Esta simple recursividad hace el trabajo.

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

Haga una función con {a: 'b', b: 'c', etc} en un cierre: -

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')

Sumando mayúsculas y 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 En algunas versiones de Javascript, puede usar en [...chars]lugar dechars.split('')



0

Aquí hay una variación del algoritmo rot13 que envié en https://stackoverflow.com/a/28490254/881441 :

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

El código de entrada en la parte inferior y el códec buscado está en la parte superior (es decir, el código de salida es el mismo que el código de entrada pero cambiado en 1). La función solo cambia las letras, es decir, si se pasa cualquier otro carácter, este códec no lo modificará.


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
Es posible que desee explicar qué ha hecho exactamente aquí y cómo ayuda en lugar de solo tener un bloque de código, ¡gracias! - ¿Quizás algunos momentos útiles en el código?
Mark Davies

String.fromCharCode () devuelve el código de carácter de la letra.
LokeshKumar

0

Basado en el incremento y decremento de la respuesta del muro de @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();
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.