Qual è un metodo che può essere utilizzato per incrementare le lettere?


98

Qualcuno sa di una libreria Javascript (ad es. Underscore, jQuery, MooTools, ecc.) Che offre un metodo per incrementare una lettera?

Mi piacerebbe essere in grado di fare qualcosa come:

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

Non sono sicuro che la sintassi che stai cercando sia possibile, ma l'operazione è possibile tramite metodi.
anson

Qual è l'applicazione?
valentinas

Risposte:


177

Soluzione semplice e diretta

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

Come altri hanno notato, lo svantaggio è che potrebbe non gestire casi come la lettera "z" come previsto. Ma dipende da cosa vuoi ottenere da esso. La soluzione sopra restituirà "{" per il carattere dopo "z", e questo è il carattere dopo "z" in ASCII, quindi potrebbe essere il risultato che stai cercando a seconda del tuo caso d'uso.


Unico generatore di stringhe

(Aggiornato 2019/05/09)

Poiché questa risposta ha ricevuto così tanta visibilità, ho deciso di espanderla un po 'oltre lo scopo della domanda originale per aiutare potenzialmente le persone che si imbattono in questo da Google.

Trovo che quello che spesso voglio è qualcosa che generi stringhe sequenziali e univoche in un certo set di caratteri (come usare solo lettere), quindi ho aggiornato questa risposta per includere una classe che lo farà qui:

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

Utilizzo:

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'

Soluzione semplice, ma non gestisce l'occorrenza di "z" o "Z".
Trent

3
una specie di buzzkill che andrà in caratteri speciali come /
Daniel Thompson

Esattamente quello che stavo cercando mentre stavo cercando di passare attraverso e scegliere i caratteri Unicode non visualizzati in un font IBM Code Page 437 della vecchia scuola. Mi hai letteralmente risparmiato ore di battitura di caratteri.
LeftOnTheMoon

1
Daniel Thompson questa soluzione fornisce informazioni più che sufficienti, puoi gestire tu stesso i casi d'angolo. Dopotutto, questo è un sito "aiutarsi a vicenda", non fare il mio lavoro per un sito web gratuito.
Bojidar Stanchev

Mi ci è voluto un po 'per capire come rendere il personaggio iniziale un argomento. Ho finito per usare ._nextId = [chars.split (''). FindIndex (x => x == start)]; Oppure avvia + 1 se vuoi che inizi 1 in più rispetto a quello che hai passato.
JohnDavid

49

Il semplice javascript dovrebbe fare il trucco:

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

1
Fascino puro, qualsiasi suggerimento per evitare spazi bianchi e caratteri speciali. coderByte ha una domanda su questo
sg28

22

E se la lettera data è z? Ecco una soluzione migliore. Va A, B, C ... X, Y, Z, AA, AB, ... ecc. Fondamentalmente incrementa le lettere come gli ID di colonna di un foglio di calcolo Excel.

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


Modificato if (same(u,'Z')){in if (u == 'Z'){e funziona perfettamente, grazie!
Sean Kendle

Sono contento che abbia funzionato e grazie per il feedback. Forse quell'errore iniziale era che la funzione intitolata same(str,char)non era stata incollata lì? Non so.
Ronnie Royston

Deve essere il caso, same()è chiaramente una funzione personalizzata. Vabbè, ==funziona, e se volessi essere assolutamente sicuro, potrei usarlo ===, ma l'ho provato e va bene. Grazie ancora!
Sean Kendle

se digiti zz otterrai la tripla A è un bug nel codice ??
Amr Ashraf

1
non credo proprio? cosa viene dopo zz? aaa vero? Non ho installato Excel su questa macchina (per ricontrollare) ma mi suona bene.
Ronnie Royston

5

Un modo possibile potrebbe essere quello definito di seguito

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

Puoi provare questo

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

Prima convertilo in numero Ascii .. Incrementalo .. poi converti da Ascii a char ..

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

Controlla FIDDLE


1
Hmm. Ha bisogno di più jQuery.
Jasper

4

Avevo bisogno di utilizzare sequenze di lettere più volte e quindi ho creato questa funzione in base a questa domanda SO. Spero che questo possa aiutare gli altri.

function charLoop(from, to, callback)
{
    var i = from.charCodeAt(0);
    var to = to.charCodeAt(0);
    for(;i<=to;i++) callback(String.fromCharCode(i));
}
  • da - lettera iniziale
  • a - ultima lettera
  • callback (letter) - funzione da eseguire per ogni lettera nella sequenza

Come usarlo:

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

Guarda questa demo funzionante


3

Aggiungendo tutte queste risposte:

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

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


2

Questo funziona bene:

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 soluzione solo per ridere

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

Questo è davvero vecchio. Ma avevo bisogno di questa funzionalità e nessuna delle soluzioni è ottimale per il mio caso d'uso. Volevo generare a, b, c ... z, aa, ab ... zz, aaa .... Questa semplice ricorsione fa il lavoro.

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

Crea una funzione con {a: 'b', b: 'c', ecc} in una chiusura: -

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

utilizzo: -

nextChar('a')

Aggiunta di lettere maiuscole e cifre: -

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

ps In alcune versioni di Javascript, puoi usare al [...chars]posto dichars.split('')



0

Ecco una variazione dell'algoritmo rot13 che ho inviato su https://stackoverflow.com/a/28490254/881441 :

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

Il codice di input in basso e il codec cercato è in alto (ovvero il codice di output è lo stesso del codice di input ma spostato di 1). La funzione cambia solo le lettere, cioè se viene passato qualsiasi altro carattere, non verrà modificato da questo 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
Potresti spiegare cosa hai fatto esattamente qui e come aiuta piuttosto che avere solo un blocco di codice, grazie! - Forse alcuni cmomenti utili nel codice?
Mark Davies

String.fromCharCode () restituisce il codice char della lettera.
LokeshKumar

0

Basato sull'incremento e il decremento della risposta del muro di @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;
  }
    
}

Utilizzo

const ids = new StringIdGenerator();

ids.next(); 
ids.prev();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.