Converte inteiro em seu equivalente de caractere, onde 0 => a, 1 => b, etc

173

Eu quero converter um número inteiro em seu caractere equivalente com base no alfabeto. Por exemplo:

0 => a
1 => b
2 => c
3 => d

Eu poderia criar uma matriz e apenas procurá-la quando precisar, mas estou me perguntando se há uma função integrada para fazer isso por mim. Todos os exemplos que encontrei no Google estão trabalhando com valores ASCII e não com a posição de um caractere no alfabeto.

VIVA LA NWO
fonte
2
As letras minúsculas são ordenadas alfabeticamente em ASCII.
Anon.
13
Mesmo os dígitos ;-)
MBq

Respostas:

324

Supondo que você queira letras minúsculas:

var chr = String.fromCharCode(97 + n); // where n is 0, 1, 2 ...

97 é o código ASCII para minúsculas 'a'. Se você quiser letras maiúsculas, substitua 97 por 65 ('A' maiúsculo). Observe que n > 25, se você sair do intervalo de letras.

Daniel Vandersluis
fonte
82

Será mais portátil em caso de extensão para outros alfabetos:

char='abcdefghijklmnopqrstuvwxyz'[code]

ou, para ser mais compatível (com nosso amado IE):

char='abcdefghijklmnopqrstuvwxyz'.charAt(code);
mbq
fonte
5
Muito mais elegante do que String.fromCharCodena minha opinião, como você disse, se estende com muita facilidade.
Sasha Chedygov
8
E quando você não precisa estender, talvez seja mais propenso a erros? abcede
Nelson Rothermel
5
O FYI JScript (IE) não suporta o operador de índice []em strings.
Crescent Fresh
4
@Crescent, o []acessador de propriedade nas strings é suportado no IE a partir do IE8 (o IE8 no modo compatível com o IE7 também não funciona), String.prototype.chatAté preferível em vez da []compatibilidade com o navegador. Por exemplo'foo'.charAt(0) == 'f'
CMS
2
@Crescent, esqueceu de mencionar que o []acessador de propriedades nas strings é padronizado no ECMAScript 5 (consulte [[GetOwnProperty]] (P) ).
CMS
29

Se você não se importa em recuperar seqüências de vários caracteres, pode suportar índices positivos arbitrários:

function idOf(i) {
    return (i >= 26 ? idOf((i / 26 >> 0) - 1) : '') +  'abcdefghijklmnopqrstuvwxyz'[i % 26 >> 0];
}

idOf(0) // a
idOf(1) // b
idOf(25) // z
idOf(26) // aa
idOf(27) // ab
idOf(701) // zz
idOf(702) // aaa
idOf(703) // aab

(Não completamente testado para erros de precisão :)

z0r
fonte
1
Função recursiva, muito legal!
John Virgolino 22/03
@mikemaccana, por que esta edição? Eu acho que dificulta a leitura. Agora eu tenho que rolar horizontalmente para ler o código.
Z0r
@ z0r Portanto, as pessoas que usam o código não precisarão corrigir a nova linha. Não há motivo para quebrar linhas arbitrariamente, os editores quebram com o tamanho de caractere de sua janela.
Mikemaccana 12/05
Isso funciona muito bem, existe uma variante para fazer o oposto?
Ethannn
Boa ideia, mas não funcionou até mudar para isso:function idOf(i) { return (i >= 26 ? idOf(Math.floor(i / 26) -1 ) : '') + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i % 26]; }
PatrickvL
19

Uma resposta simples seria (26 caracteres):

String.fromCharCode(97+n);

Se o espaço for precioso, você pode fazer o seguinte (20 caracteres):

(10+n).toString(36);

Pense no que você poderia fazer com todos esses bytes extras!

Como isso funciona, você converte o número na base 36, para ter os seguintes caracteres:

0123456789abcdefghijklmnopqrstuvwxyz
^         ^
n        n+10

Ao compensar por 10, os caracteres começam em avez de 0.

Não tenho muita certeza sobre a velocidade de execução dos dois exemplos diferentes do lado do cliente.

Dan
fonte
2
Eu gostava de sua base 36 criatividade
Josh
6

String.fromCharCode do Javascript (código1, código2, ..., códigoN) recebe um número infinito de argumentos e retorna uma sequência de letras cujos valores ASCII correspondentes são código1, código2, ... códigoN. Como 97 é 'a' em ASCII, podemos ajustar a sua indexação adicionando 97 ao seu índice.

function indexToChar(i) {
  return String.fromCharCode(i+97); //97 in ASCII is 'a', so i=0 returns 'a', 
                                    // i=1 returns 'b', etc
}
cem watts
fonte
4
Bem, para ser pedante, é preciso um número variável de argumentos, não um número infinito .
precisa saber é
4

Não gosto de todas as soluções que usam números mágicos como 97ou 36.

const A = 'A'.charCodeAt(0);

let numberToCharacter = number => String.fromCharCode(A + number);

let characterToNumber = character => character.charCodeAt(0) - A;

isso assume letras maiúsculas e inicia 'A' em 0.

junvar
fonte
3

Use String.fromCharCode. Isso retorna uma sequência de um valor Unicode, que corresponde aos primeiros 128 caracteres do ASCII.

var a = String.fromCharCode(97);
James Westgate
fonte
3

Lá vai você: (a-zA-Z)

function codeToChar( number ) {
  if ( number >= 0 && number <= 25 ) // a-z
    number = number + 97;
  else if ( number >= 26 && number <= 51 ) // A-Z
    number = number + (65-26);
  else
    return false; // range error
  return String.fromCharCode( number );
}

entrada: 0-51, ou retornará falso (erro de intervalo);

OU:

var codeToChar = function() {
  var abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
  return function( code ) {
    return abc[code];
  };
})();

retorna indefinido em caso de erro de intervalo. NOTA: a matriz será criada apenas uma vez e, devido ao fechamento, estará disponível para a nova função codeToChar. Eu acho que é ainda mais rápido que o primeiro método (é apenas uma pesquisa basicamente).

gblazex
fonte
Isso funciona com ASCII, preciso trabalhar com a posição do caractere no alfabeto.
VIVA LA NWO
@VIVA - Eu acho que você poderia ter resolvido isso? @Galambalaza - Eu acho que você quer 65, não 64
James Westgate
Eu apenas mostrei como é simples. ele poderia ter resolvido isso. mas lá vai você. veja a atualização
gblazex
1

O único problema com a ótima solução do @ mikemaccana é que ele usa o operador binário >> que é caro, em termos de desempenho. Sugiro esta modificação ao seu excelente trabalho como uma ligeira melhoria que talvez seus colegas possam ler com mais facilidade.

const getColumnName = (i) => {
     const previousLetters = (i >= 26 ? getColumnName(Math.floor(i / 26) -1 ) : '');
     const lastLetter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i % 26]; 
     return previousLetters + lastLetter;
}

Ou como uma linha

const getColumnName = i => (i >= 26 ? getColumnName(Math.floor(i / 26) -1 ) : '') + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i % 26];

Exemplo:

getColumnName(0); // "A"
getColumnName(1); // "B"
getColumnName(25); // "Z"
getColumnName(26); // "AA"
getColumnName(27); // "AB"
getColumnName(80085) // "DNLF"
Pandem1c
fonte
0

Experimentar

(n+10).toString(36)

Kamil Kiełczewski
fonte
-3

Supondo que você queira letras maiúsculas:

function numberToLetter(num){
        var alf={
            '0': 'A', '1': 'B', '2': 'C', '3': 'D', '4': 'E', '5': 'F', '6': 'G'
        };
        if(num.length== 1) return alf[num] || ' ';
        return num.split('').map(numberToLetter);
    }

Exemplo:

numberToLetter ('023') é ["A", "C", "D"]

numberToLetter ('5') é "F"

função número para letra

Rafael Corrêa Gomes
fonte