Zamień liczbę całkowitą na jej odpowiednik znakowy, gdzie 0 => a, 1 => b itd

173

Chcę przekonwertować liczbę całkowitą na jej odpowiednik znakowy na podstawie alfabetu. Na przykład:

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

itp. Mógłbym zbudować tablicę i po prostu ją wyszukać, kiedy jej potrzebuję, ale zastanawiam się, czy jest wbudowana funkcja, która zrobi to za mnie. Wszystkie przykłady, które znalazłem za pośrednictwem Google, działają z wartościami ASCII, a nie z pozycją znaku w alfabecie.

VIVA LA NWO
źródło
2
Małe litery są uporządkowane alfabetycznie w ASCII.
Anon.
13
Nawet cyfry ;-)
mbq

Odpowiedzi:

324

Zakładając, że chcesz mieć małe litery:

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

97 to kod ASCII dla małych liter „a”. Jeśli chcesz używać wielkich liter, zamień 97 na 65 (wielkie litery „A”). Zwróć uwagę, że jeśli n > 25wyjdziesz z zakresu liter.

Daniel Vandersluis
źródło
82

Będzie bardziej przenośny w przypadku rozszerzenia na inne alfabety:

char='abcdefghijklmnopqrstuvwxyz'[code]

lub, aby być bardziej kompatybilnym (z naszym ukochanym IE):

char='abcdefghijklmnopqrstuvwxyz'.charAt(code);
mbq
źródło
5
O wiele bardziej elegancki niż String.fromCharCodemoim zdaniem, jak powiedziałeś, bardzo łatwo się rozciąga.
Sasha Chedygov
8
A kiedy nie potrzebujesz przedłużania, może bardziej podatny na błędy? abcede
Nelson Rothermel
5
FYI JScript (IE) nie obsługuje operatora indeksu []w łańcuchach.
Crescent Fresh
4
@Crescent, metoda dostępu do []ciągów znaków jest obsługiwana w IE od IE8 w górę (IE8 w trybie zgodności z IE7 również nie działa), String.prototype.chatAtjest preferowana zamiast []zgodności z przeglądarką. Np.'foo'.charAt(0) == 'f'
CMS
2
@Crescent, zapomniałem wspomnieć, że []akcesor właściwości w łańcuchach jest ustandaryzowany w ECMAScript 5 (patrz [[GetOwnProperty]] (P) ).
CMS
29

Jeśli nie masz nic przeciwko odzyskiwaniu wieloznakowych ciągów, możesz obsługiwać dowolne dodatnie indeksy:

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

(Niezupełnie przetestowane pod kątem błędów precyzji :)

z0r
źródło
1
Funkcja rekurencyjna, bardzo ładna!
John Virgolino
@mikemaccana, dlaczego ta zmiana? Myślę, że to utrudnia czytanie. Teraz muszę przewijać w poziomie, aby odczytać kod.
z0r
@ z0r Więc ludzie używający kodu nie będą musieli naprawiać nowej linii. Nie ma powodu, aby dowolnie łamać wiersze, redaktorzy będą zawijać do rozmiaru znaków swojego okna.
mikemaccana
To działa świetnie, czy istnieje wariant, w którym można zrobić coś odwrotnego?
Ethannn,
Niezły pomysł, ale nie zadziałał, dopóki nie zmienił się w następujący:function idOf(i) { return (i >= 26 ? idOf(Math.floor(i / 26) -1 ) : '') + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i % 26]; }
PatrickvL
19

Prosta odpowiedź brzmiałaby (26 znaków):

String.fromCharCode(97+n);

Jeśli miejsce jest cenne, możesz wykonać następujące czynności (20 znaków):

(10+n).toString(36);

Pomyśl, co mógłbyś zrobić z tymi wszystkimi dodatkowymi bajtami!

Jak to działa, konwertujesz liczbę do podstawy 36, więc masz następujące znaki:

0123456789abcdefghijklmnopqrstuvwxyz
^         ^
n        n+10

Poprzez przesunięcie o 10 znaki zaczynają się od azamiast0 .

Nie jestem jednak do końca pewien, jak szybko działałyby dwa różne przykłady po stronie klienta.

Dan
źródło
2
Podobała mi się twoja podstawowa kreatywność 36
Josh
6

JavaScript String.fromCharCode (kod1, kod2, ..., kodN) przyjmuje nieskończoną liczbę argumentów i zwraca ciąg liter, których odpowiadające wartości ASCII to kod1, kod2, ... kodN. Ponieważ 97 to „a” w ASCII, możemy dostosować indeksowanie, dodając 97 do indeksu.

function indexToChar(i) {
  return String.fromCharCode(i+97); //97 in ASCII is 'a', so i=0 returns 'a', 
                                    // i=1 returns 'b', etc
}
sto watów
źródło
4
Cóż, żeby być pedantycznym, potrzeba zmiennej liczby argumentów, a nie nieskończonej liczby.
wchargin
4

Nie podobają mi się wszystkie rozwiązania wykorzystujące magiczne liczby, takie jak 97lub 36.

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

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

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

zakłada to wielkie litery i zaczyna się od „A” od 0.

junvar
źródło
3

Użyj String.fromCharCode. Zwraca ciąg z wartości Unicode, która pasuje do pierwszych 128 znaków ASCII.

var a = String.fromCharCode(97);
James Westgate
źródło
3

Proszę bardzo: (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 );
}

input: 0-51, lub zwróci false (błąd zakresu);

LUB:

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

zwraca wartość undefined w przypadku błędu zakresu. UWAGA: tablica zostanie utworzona tylko raz i ze względu na zamknięcie będzie dostępna dla nowej funkcji codeToChar. Myślę, że jest to nawet szybsze niż pierwsza metoda (w zasadzie to tylko wyszukiwanie).

gblazex
źródło
To działa z ASCII, muszę pracować z pozycją znaku w alfabecie.
VIVA LA NWO
@VIVA - Myślę, że mogłeś to rozwiązać? @Galambalaza - Myślę, że chcesz 65, a nie 64
James Westgate
właśnie pokazałem, jakie to proste. mógł to rozwiązać. ale proszę bardzo. zobacz aktualizację
gblazex
1

Jedynym problemem ze świetnym rozwiązaniem @ mikemaccana jest to, że używa operatora binarnego >>, który jest kosztowny, jeśli chodzi o wydajność. Proponuję tę modyfikację jego wspaniałej pracy jako drobne ulepszenie, które może być łatwiejsze dla Twoich kolegów.

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

Lub jako jednowierszowy

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

Przykład:

getColumnName(0); // "A"
getColumnName(1); // "B"
getColumnName(25); // "Z"
getColumnName(26); // "AA"
getColumnName(27); // "AB"
getColumnName(80085) // "DNLF"
Pandem1c
źródło
0

Próbować

(n+10).toString(36)

Kamil Kiełczewski
źródło
-3

Zakładając, że chcesz mieć duże litery:

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

Przykład:

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

numberToLetter ('5') to „F”

funkcja od liczby do litery

Rafael Corrêa Gomes
źródło