This is probably an unusual request, but for my script I need a function that increments by letter instead of number. For example:
This is a numeric example:
var i = 0;
while(condition){
window.write('We are at '+i);
++i;
}
Essentially, I want to count with letters, like Microsoft Excel does, instead of numbers. So instead of printing "We are at 0", "We are at 1", "We are at 2", etc., I need to print "We are at A", "We are at B", "We are at C", etc.
To mimic Excel (the only example I can think of), after reaching index 25 (Z), we could move on to 'AA', 'AB', 'AC', etc.
So it would work great like so:
var i = 0;
while(condition){
window.write('We are at '+toLetter(i));
++i;
}
Even better if somebody can write a function that then converts a letter back into a digit, i.e. toNumber('A') = 0 or toNumber('DC') = 107 (I think).
Thanks!
This is probably an unusual request, but for my script I need a function that increments by letter instead of number. For example:
This is a numeric example:
var i = 0;
while(condition){
window.write('We are at '+i);
++i;
}
Essentially, I want to count with letters, like Microsoft Excel does, instead of numbers. So instead of printing "We are at 0", "We are at 1", "We are at 2", etc., I need to print "We are at A", "We are at B", "We are at C", etc.
To mimic Excel (the only example I can think of), after reaching index 25 (Z), we could move on to 'AA', 'AB', 'AC', etc.
So it would work great like so:
var i = 0;
while(condition){
window.write('We are at '+toLetter(i));
++i;
}
Even better if somebody can write a function that then converts a letter back into a digit, i.e. toNumber('A') = 0 or toNumber('DC') = 107 (I think).
Thanks!
Share Improve this question asked Jun 18, 2012 at 19:07 M MillerM Miller 5,63210 gold badges48 silver badges69 bronze badges 8- 2 Sorry for asking, but what did you try? So far it looks like a homework to me. – alf Commented Jun 18, 2012 at 19:09
- So you need to write toNumber() and toLetter(). This looks like a very simple algorithmic quest. Show us what you tried. – Al Kepp Commented Jun 18, 2012 at 19:10
- You could build an array of letters, and then compare your count to the key in the array (making sure to compensate for the "0" position). If your count starts at zero, then you're good. – gtr1971 Commented Jun 18, 2012 at 19:12
- I found a solution by thinking in terms of base 26. frugalcoder.us/post/2011/02/24/… – M Miller Commented Jun 18, 2012 at 19:20
- That code is pretty terrible. It converts the number to a string, and then goes back and fixes it. It'd be better (and easier) to just convert it directly. – Pointy Commented Jun 18, 2012 at 19:22
7 Answers
Reset to default 42Here's a simple recursive function to convert the numbers to letters.
It's one-based, so 1 is A, 26 is Z, 27 is AA.
function toLetters(num) {
"use strict";
var mod = num % 26,
pow = num / 26 | 0,
out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z');
return pow ? toLetters(pow) + out : out;
}
Here's a matching function to convert the strings back to numbers:
function fromLetters(str) {
"use strict";
var out = 0, len = str.length, pos = len;
while (--pos > -1) {
out += (str.charCodeAt(pos) - 64) * Math.pow(26, len - 1 - pos);
}
return out;
}
A test: http://jsfiddle.net/St6c9/
Something like this you mean?
function num2chars(num, upper){
num2chars.letters = num2chars.letters || 'abcdefghijklmnopqrstuvwxyz'.split('');
var ret = repeat(num2chars.letters[num%26],Math.floor(num/26));
function repeat(chr,n){
if (n<1) {return chr;}
return new Array(n+1).join(chr);
}
return upper ? ret.toUpperCase() : ret;
}
//usage
while(i<104){
console.log(num2chars((i+=1),true));
}
//=> A..Z, AA..ZZ, AAA..ZZZ
For future readers I leave what I think is a more straightforward solution:
const aLetterCode = 97
const getLetterFromId = (number) => String.fromCharCode(aLetterCode + number)
console.log('code 0 ->', getLetterFromId(0)) // a
console.log('code 1 ->', getLetterFromId(1)) // b
console.log('code 12 ->', getLetterFromId(12)) // m
Create an array of letters A, B, C, D, etc. then call A by using array[0] since 0 is the index of A you can use array[i] as the index, just validate so i can't be over 25.
Use either of these ways to create the array:
var alphabet = new Array("A","B","C");
var alphabet = new Array(25);
alphabet[0] = "A";
alphabet[1] = "B";
alphabet[2] = "C";
instead of toLetter(i);
use alphabet[i];
Try the following. Tried and tested in few minutes
var prefix = Array('','A','B'); //this will extends to 3x26 letters. Determines the Max generated
//first element of prefix is `''` so you can have A B C D
var prefix = Array('','A','B');
var alphabets = Array('A','B','C','D'); //extend this to Z
var letters = Array();
function fillArray()
{
var prefix_len = prefix.length;
var array_len = prefix_len * alphabets.length;
var alpha_len = alphabets.length;
for(var i=0; i<prefix_len; i++)
{
for(var a=0; a<alpha_len; a++)
letters.push(''+prefix[i]+alphabets[a]);
}
}
function getLetter(index)
{
return letters[index];
}
function generateTestValues()
{
fillArray();
//make sure 10 is less than letters.length
for(var i=0; i<10; i++)
document.write(getLetter(i)+' '); //A B C D AA AB AC AD BA BB BC....
}
HTML
<span id="clickable" onclick="generateTestValues()">Click Me</span>
Thats how you can generate random letters:
function getRandomArbitrary(min, max) {
max = Math.ceil(max);
min = Math.floor(min);
return Math.round(Math.random() * (max - min) + min);
}
function assignLetter(){
var group = ['A', 'B', 'C', 'D'];
var text = 'We are at ';
var str = '';
str = text + group[getRandomArbitrary(0, group.length-1)];
return str;
}
assignLetter();
Try the following:
function getCharCode(value) {
if (value===null || value === undefined) return "";
if (value < 26) return String.fromCharCode(65 + value);
return (
getCharCode(Number(value / 26) - 1) + String.fromCharCode(65 + (value % 26))
);
}