What is a method that can be used to increment letters?

Does anyone know of a Javascript library (e.g. underscore, jQuery, MooTools, etc.) that offers a method of incrementing a letter?

I would like to be able to do something like:

"a"++; // would return "b"
104925 次浏览

I was able to solve the problem by doing Proper Indexing on the columns which were used to search in the query and applying appropriate constraints wherever required.

I faced the same issue because I was querying db for more than 1000 iterations.

Plain javascript should do the trick:

String.fromCharCode('A'.charCodeAt() + 1) // Returns B
I have used try and finally in my code. But was still getting error.

Simple, direct solution

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

To solve this I just logged into oracle db and ran below query:

As others have noted, the drawback is it may not handle cases like the letter 'z' as expected. But it depends on what you want out of it. The solution above will return '{' for the character after 'z', and this is the character after 'z' in ASCII, so it could be the result you're looking for depending on what your use case is.


ALTER SYSTEM SET open_cursors = 8000 SCOPE=BOTH;

Unique string generator

And this solved my problem immediately.

(Updated 2019/05/09)

the character after 'z', and this is the character after 'z' in ASCII, so it could be the result you're looking for depending on what your use case is.


Since this answer has received so much visibility I've decided to expand it a bit beyond the scope of the original question to potentially help people who are stumbling on this from Google.

Unique string generator

I find that what I often want is something that will generate sequential, unique strings in a certain character set (such as only using letters), so I've updated this answer to include a class that will do that here:

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

(Updated 2019/05/09)

Usage:

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'

Since this answer has received so much visibility I've decided to expand it a bit beyond the scope of the original question to potentially help people who are stumbling on this from Google.

Adding upon all these answers:

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

I find that what I often want is something that will generate sequential, unique strings in a certain character set (such as only using letters), so I've updated this answer to include a class that will do that here:

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

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

  • I did wonder about the load balancers sending a redirect on the initial request, so that the browser initially requests www.mydomain.example and gets redirected to www34.mydomain.example. That works quite well, until the node goes down - and sites like Facebook don't do that. How do they do it?

  • Put a L3 load-balancer that distributes IP packets based on source-IP-port hash to your WebSocket server farm. Since the L3 balancer maintains no state (using hashed source-IP-port) it will scale to wire speed on low-end hardware (say 10GbE). Since the distribution is deterministic (using hashed source-IP-port), it will work with TCP (and hence WebSocket).

    What if the given letter is z? Here is a better solution. It goes A,B,C... X,Y,Z,AA,AB,... etc. Basically it increments letters like the column ID's of an Excel spreadsheet.

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

    This one does work well:

    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'
    

    Also note that a 64k hard limit only applies to outgoing TCP/IP for a given (source) IP address. It does not apply to incoming TCP/IP. We have tested Autobahn (a high-performance WebSocket server) with 200k active connections on a 2 core, 4GB RAM VM.

    This is really old. But I needed this functionality and none of the solutions are optimal for my use case. I wanted to generate a, b, c...z, aa,ab...zz, aaa... . This simple recursion does the job.

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

    p.s. In some versions of Javascript, you can use [...chars] instead of chars.split('')

    Note that if your websocket server logic runs on nodejs with socket.io, you can tell socket.io to use a shared redis key/value store for synchronization.

    One possible way could be as defined below

    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 ...
    
    
    
    This way you don't even have to care about the load balancer, events will propagate among the server instances.

    var io = require('socket.io')(3000);
    var redis = require('socket.io-redis');
    io.adapter(redis({ host: 'localhost', port: 6379 }));
    

    A just for laughs solution

    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"));

    Here is a variation of the rot13 algorithm I submitted on https://stackoverflow.com/a/28490254/881441:

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

    See: Socket IO - Using multiple nodes

    The input code in the bottom and the looked up codec is on the top (i.e. the output code is the same as the input code but shifted by 1). The function only changes letters, i.e. if any other character is passed in, it will be unchanged by this codec.

    
    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;
    
    
    

    But at some point I guess redis can become the bottleneck...

    Based on @Nathan wall answer increment and decrement

    // 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;
    }
        
    
    }
    
    lice(-1).charCodeAt(0);

    Usage

    const ids = new StringIdGenerator();
    
    
    ids.next();
    ids.prev();
    
    var z = this._nextLetter(l);

    This is my function to get increment letters to infinity in Javascript( for uppercase only)

    function getNextStringId(str) {
    let index = str.length-1;
    let baseCode= str.charCodeAt(index);
    do{
    baseCode= str.charCodeAt(index);
    let strArr= str.split("");
    if(strArr[index] == "Z"){
    strArr[index] = "A";
    if(index==0){
    strArr.unshift("A");
    }
    }
    else{
    strArr[index]= String.fromCharCode(baseCode + 1);
    }
    str= strArr.join("");
    index--;
    } while(baseCode == 90)
    return str;
    }
    
    
    
    
    getNextStringId("A") // B
    getNextStringId("Z") // AA
    getNextStringId("ABZZ") // ACAA
    
    if(z==='A'){

    Zar and Nathan's answers both good stuff. Everything else here seems overcomplicated for me.

      this._chars = p.slice(0,-1) + this._nextLetter(q.slice(-1).charCodeAt(0)) + z;
    • I wanted to specify my own character set so didn't bother with charCode
    • return p.slice(0,-1) + this._nextLetter(q.slice(-1).charCodeAt(0)) + z;
    • I didn't need multi character recursion
    • } else {
    • added 0 to my character set for error handling (while (letter != 0))
    this._chars = p+z;

    I ended up with this:

    let letter = "a";
    let alphabet = "abcdefghijklmnopqrstuvwxyz0";
    let nextletter = alphabet.substr(alphabet.indexOf(letter)+1,1);
    
    return p + z;

    Then I can very simply add in further dimensions:

    let alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!£$%^&*_0";
    

    function increment(e) {
    let letter = e.value;
    let alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0";
    let next = alphabet.substr(alphabet.indexOf(letter)+1,1);
    document.getElementById("result").innerHTML = next;
    };
    <input type="text" minlength="1" maxlength="1" onchange="increment(this)" placeholder="type letter">
    <button>Update</button>
    <div id="result"></div>