Convert number to letters

I want to make an integer into a string, (like in excel where one side counts in letters). For example: 1 = A, 2 = B, 27 = AA, 28 = AB

Basically, I need an efficient way to order things alphabetically using an integer.

I have looked around on the web but I don’t know what this is actually called. I tried to think of ways I could go about making this myself but I got stuck.

Any advice appreciated.

If you’re just trying to order things alphabetically there are easier ways.

What are you really trying to do? This seems like a strange problem to want to solve, but maybe you have a good reason.

local Dict = {
 [1] = "a" -- ect
}

function StringToNumber(str)
 local num = ""
for i,v in pairs(string.split(str,"")) do
  for a,b in pairs(Dict) do
   if b == v:lower() then
    num = num .. tostring(a or 1) -- default A 
   end
  end
 end
 return num
end
function NumberToString(str)
 local num = ""
for i,v in pairs(string.split(str,"")) do
  for a,b in pairs(Dict) do
   if a == v:lower() then
    num = num .. tostring(b or "a") -- default A 
   end
  end
 end
 return num
end
2 Likes

The easiest way to do this is just to use the base 10 → base x conversion algorithm:

local alphabet = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}

function toBase26(x)
	local result = ""
	if x < 1 then return result end
	
	local quotient = x
	local remainder = -1
	
	while quotient ~= 0 do
		local dec = quotient - 1
		remainder = dec % #alphabet
		quotient = math.floor(dec / #alphabet)
		result = alphabet[remainder + 1] .. result -- Compensated for lua's index 1 start
	end
	return result
end

This function specifically converts to base 26 because that we’ve defined 26 symbols in our alphabet, but it could be of any size.

The basic gist of the conversion is like this:

  • Divide the value by the base and keep the remainder.
  • The remainder is the positional value of the symbol in the array.
  • Floor (round down) the number you get after division and then repeat the process until the value is 0.
  • The resulting string at this point if you’re just adding to it will be in reverse order so make sure to reverse it again to get it in the right order (in the code above we prepend the value instead of appending it, so this part is not needed)

This works for converting from base 10 to any base, just add more symbols to your alphabet.

5 Likes

Actually an even easier way is, by using math.char:

string.char(x + 64) 

Note that when X would go over 26 it would become a different character than intended, so you should limit that.

3 Likes

And string.byte(c) - 64 for the other way :slight_smile:

Unfortunately that only allows you to use a specific characterset which isn’t always desirable for everyone. My answer works with a custom alphabet that you can add and remove from, and it will work with any base you choose. Your answer is fine for the very specific base 26 with a standardized alphabet, but it is not generalized.

This is dead, but here’s a way:

local function NumberToLetter(Number)
	if Number >= 1 and Number <= 26 then
		return string.char(Number + string.byte("A") - 1)
	else
		error("Not in alphabetical range")
	end
end