Konversi integer menjadi karakter yang setara, di mana 0 => a, 1 => b, dll

173

Saya ingin mengubah bilangan bulat menjadi karakter yang setara berdasarkan alfabet. Sebagai contoh:

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

dll. Saya dapat membangun sebuah array dan hanya mencarinya ketika saya membutuhkannya tetapi saya bertanya-tanya apakah ada fungsi bawaan untuk melakukan ini untuk saya. Semua contoh yang saya temukan melalui Google bekerja dengan nilai-nilai ASCII dan bukan posisi karakter dalam alfabet.

VIVA LA NWO
sumber
2
Huruf kecil dipesan sesuai abjad di ASCII.
Anon.
13
Bahkan digit ;-)
mbq

Jawaban:

324

Dengan asumsi Anda ingin huruf kecil:

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

97 adalah kode ASCII untuk huruf kecil 'a'. Jika Anda ingin huruf besar, ganti 97 dengan 65 (huruf besar 'A'). Perhatikan bahwa jika n > 25, Anda akan keluar dari kisaran huruf.

Daniel Vandersluis
sumber
82

Akan lebih portabel jika memperluas ke huruf lain:

char='abcdefghijklmnopqrstuvwxyz'[code]

atau, agar lebih kompatibel (dengan IE yang kami cintai):

char='abcdefghijklmnopqrstuvwxyz'.charAt(code);
mbq
sumber
5
Jauh lebih elegan daripada String.fromCharCode menurut saya, seperti yang Anda katakan, itu meluas dengan sangat mudah.
Sasha Chedygov
8
Dan ketika Anda tidak perlu memperpanjang, mungkin lebih rentan terhadap kesalahan? abcede
Nelson Rothermel
5
FYI JScript (IE) tidak mendukung operator indeks []pada string.
Crescent Fresh
4
@Crescent, []accessor properti pada string didukung pada IE dari IE8 ke atas (IE8 dalam mode compat IE7 juga tidak berfungsi), String.prototype.chatAtlebih disukai daripada []kompatibilitas browser. Misalnya'foo'.charAt(0) == 'f'
CMS
2
@Crescent, lupa menyebutkan bahwa []accessor properti pada string distandarisasi pada ECMAScript 5 (lihat [[GetOwnProperty]] (P) ).
CMS
29

Jika Anda tidak keberatan mendapatkan string multi-karakter kembali, Anda dapat mendukung indeks positif sewenang-wenang:

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

(Tidak sepenuhnya diuji untuk kesalahan presisi :)

z0r
sumber
1
Fungsi rekursif, sangat bagus!
John Virgolino
@mikemaccana, mengapa suntingan ini? Saya pikir itu membuatnya lebih sulit untuk dibaca. Sekarang saya harus gulir secara horizontal untuk membaca kode.
z0r
@ z0r Jadi orang yang menggunakan kode ini tidak perlu memperbaiki baris baru. Tidak ada alasan untuk memecah baris secara sewenang-wenang, editor akan membungkus dengan ukuran karakter jendela mereka.
mikemaccana
Ini bekerja dengan baik, apakah ada varian untuk melakukan yang sebaliknya?
Ethannn
Gagasan bagus, tetapi tidak berhasil sampai diubah menjadi ini:function idOf(i) { return (i >= 26 ? idOf(Math.floor(i / 26) -1 ) : '') + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i % 26]; }
Patrickv
19

Jawaban sederhananya adalah (26 karakter):

String.fromCharCode(97+n);

Jika ruang berharga, Anda dapat melakukan hal berikut (20 karakter):

(10+n).toString(36);

Pikirkan tentang apa yang dapat Anda lakukan dengan semua byte ekstra itu!

Cara kerjanya adalah Anda mengonversi nomor menjadi basis 36, sehingga Anda memiliki karakter berikut:

0123456789abcdefghijklmnopqrstuvwxyz
^         ^
n        n+10

Dengan mengimbangi dengan 10 karakter dimulai pada abukan0 .

Tidak sepenuhnya yakin tentang seberapa cepat menjalankan dua contoh berbeda sisi klien akan membandingkan.

Dan
sumber
2
Saya menikmati kreativitas dasar 36 Anda
Josh
6

String.fromCharCode dari Javascript (code1, code2, ..., codeN) mengambil jumlah argumen yang tak terbatas dan mengembalikan serangkaian huruf yang nilai ASCII terkaitnya adalah code1, code2, ... codeN. Karena 97 adalah 'a' di ASCII, kami dapat menyesuaikan pengindeksan Anda dengan menambahkan 97 ke indeks Anda.

function indexToChar(i) {
  return String.fromCharCode(i+97); //97 in ASCII is 'a', so i=0 returns 'a', 
                                    // i=1 returns 'b', etc
}
seratus watt
sumber
4
Nah, untuk menjadi bertele-tele, dibutuhkan sejumlah variabel argumen, bukan angka tak terbatas .
wchargin
4

Saya tidak suka semua solusi yang menggunakan angka ajaib seperti 97atau 36.

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

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

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

ini mengasumsikan huruf besar dan mulai 'A' pada 0.

junvar
sumber
3

Gunakan String.fromCharCode. Ini mengembalikan string dari nilai Unicode, yang cocok dengan 128 karakter ASCII pertama.

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

Ini dia: (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, atau itu akan mengembalikan false (range error);

ATAU:

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

mengembalikan tidak terdefinisi dalam hal kesalahan rentang. CATATAN: array akan dibuat hanya sekali dan karena penutupan itu akan tersedia untuk fungsi codeToChar yang baru. Saya kira ini bahkan lebih cepat daripada metode pertama (itu hanya pencarian pada dasarnya).

gblazex
sumber
Itu bekerja dengan ASCII, saya perlu bekerja dengan posisi karakter dalam alfabet.
VIVA LA NWO
@VIVA - Saya pikir Anda bisa menyelesaikan ini? @Galambalaza - Saya pikir Anda ingin 65 tidak 64
James Westgate
Saya hanya menunjukkan betapa sederhananya itu. dia bisa menyelesaikan ini. tapi begitulah. lihat pembaruan
gblazex
1

Satu-satunya problemo dengan solusi hebat @ mikemaccana adalah menggunakan binary >> operator yang mahal, kinerja-bijaksana. Saya menyarankan modifikasi ini pada pekerjaan besarnya sebagai sedikit perbaikan yang mungkin bisa dibaca oleh rekan Anda dengan lebih mudah.

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

Atau sebagai one-liner

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

Contoh:

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

Mencoba

(n+10).toString(36)

Kamil Kiełczewski
sumber
-3

Dengan asumsi Anda ingin huruf besar:

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

Contoh:

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

numberToLetter ('5') adalah "F"

fungsi angka ke huruf

Rafael Corrêa Gomes
sumber