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.


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.


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

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


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.


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
}

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.


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

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


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"


-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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.