Convert a Letter Into a Number and Vice Versa

Howdy folks, I'm trying to figure out if there's a way to convert a letter into it's corresponding number..and by that I mean it's number according to it's place in the alphabet.

So "A" would become "1", "K" would become "11" and so forth.

After that, how would I convert that number back into a letter?

Google search and a search of the forum here didn't produce anything that I could see.

I'm trying to figure out a new way of doing some things in a Numbers spreadsheet.

Thanks in advance for any help!

-Chris

I just did this EXACT thing yesterday!

This goes from 0-9 to a-k. You can figure out the rest.

EDIT: I just woke up. I meant it should have been a-j. The ranges have to match.

Hmm.... I can't seem to get it to work with letters and numbers beyond "j" and "9", I tried a wide range of combinations but it doesn’t return the correct results. Any ideas?

As I said, I just woke up. I thought you wanted a digit by digit replacement. I see now that's not what you wanted. I'm sorry. Let me reconsider completely.

I think this can be done by "sed", easily enough. Coincidentally, I did something very similar to this yesterday. It should take me a few minutes to write up for you.

Hey Chris,

Google: script convert letter to number

Basic letter to number JavaScript:

(() => {

   const alphaVal = (s) => s.toLowerCase().charCodeAt(0) - 97 + 1
   return alphaVal('a')

})();

Basic AppleScript:

set alphaString to "abcdefghijklmnopqrstuvwxyz"
set numList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}

set theLetter to "z"

set letterOffset to offset of theLetter in alphaString
set theNumber to item letterOffset in numList

That should get you started.

-ccs

That's a wonderful program and I knew it would appear, I just wasn't sure if you'd beat me to it. Here's my solution for letter to number. (I added spaces so that the reverse would be possible.)

Number to letter is something I won't type up because your solution will probably be chosen.

Thanks Chris, that works great and I was able to integrate it into an AppleScript I'm working on.

I have not been able to wrap my head fully around the logic behind it (still at work so haven't been able to delve into it too deeply), but does this same principle work to convert the number back into the letter it corresponded to initially?

Thank you for this example! While I will likely stick with AppleScript since this is part of a great AppleScript I am trying to write (and I know absolutely zero about shell scripts), I will hang on to this and experiment with it to try and learn a little more about shell scripts. :grin:

As they said in "The Princess Bride," "As you wish."

If you are curious, try both of those algorithms and see if one is faster. Shell scripts look convoluted but they can be extremely speedy.

Simple...

Character offset gives the character position in the string, and the list allows to you specify an item by number – so they match up perfectly.

Too bad AppleScript doesn't have the ability to directly return the item-offset in a list. Although I believe that can be done with AppleScriptObjC, I don't know how offhand.

Nor have I explored hashes in AppleScriptObjC.

-Chris

Using JS functions similar to those shown by @ccstone, but also allowing for unicode and local character sets:

(() => {
    "use strict";

    const main = () => {
        const
            cs = enumFromToChar("A")("Z"),
            lowers = enumFromToChar("a")("z"),
            alphaCodes = cs.map(ord);

        // The standard ordinal codes for [A..Z] are [65..90]
        console.log(alphaCodes);

        // So subtracting 64 will give you a [1..26] mapping.
        console.log(
            cs.map(c => ord(c) - 64)
        );

        // and in the other direction (Int -> Char) we need
        // to add 64

        console.log(
            enumFromTo(1)(26).map(n => chr(64 + n))
        );

        // For lower case [a..z] the standard ordinal codes 
        // are [97 .. 122]
        console.log(lowers.map(ord));

        // So we can shift that to 1..26 by deleting 96
        console.log(
            lowers.map(c => ord(c) - 96)
        );

        // and we can map [1..26] to [a..z] by adding 96
        console.log(
            enumFromTo(1)(26).map(n => chr(96 + n))
        );
    };


    // --------------------- GENERIC ---------------------

    // chr :: Int -> Char
    const chr = x =>
        // The character at unix code-point x.
        String.fromCodePoint(x);


    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);


    // enumFromToChar :: Char -> Char -> [Char]
    const enumFromToChar = m => n => {
        const [intM, intN] = [m, n].map(
            x => x.codePointAt(0)
        );

        return Array.from({
            length: Math.floor(intN - intM) + 1
        }, (_, i) => String.fromCodePoint(intM + i));
    };


    // ord :: Char -> Int
    const ord = c =>
        // Unicode ordinal value of the character.
        c.codePointAt(0);

    // toLower :: String -> String
    const toLower = s =>
        // Lower-case version of string.
        s.toLocaleLowerCase();


    // toUpper :: String -> String
    const toUpper = s =>
        s.toLocaleUpperCase();

    return main();
})();

So I wrote the shell script like it appears in your image... but it's not working for some reason.

2021-12-16 18:47:39 Execute a Shell Script failed with script error: text-script: line 1: sed: command not found. Macro “test shell script to convert letter to number” cancelled (while executing Execute Shell Script).

Some issue with my ENV I run shell scripts from in Keyboard Maestro? I'm not knowledgeable about shell scripts besides the basics on installing HomeBrew and certain apps...

I did run which sed in Terminal and it returned /usr/bin/sed so I tried setting my ENV_PATH variable to that before running this macro but it returned the same error.

test shell script to convert letter to number.kmmacros (2.2 KB)

O! I see the error. Your O is missing a "/".

I should have uploaded the macro. Sorry, that must have been a pain typing in. But hey, I had to type it! If I still have it I'll paste it here in a minute.

HERE:

sed "s/A/ 1 /g;s/B/ 2 /g;s/C/ 3 /g;s/D/ 4 /g;s/E/ 5 /g;s/F/ 6 /g;s/G/ 7 /g;s/H/ 8 /g;s/I/ 9 /g;s/J/ 10 /g;s/K/ 11 /g;s/L/ 12 /g;s/M/ 13 /g;s/N/ 14 /g;s/O/ 15 /g;s/P/ 16 /g;s/Q/ 17 /g;s/R/ 18 /g;s/S/ 19 /g;s/T/ 20 /g;s/U/ 21 /g;s/V/ 22 /g;s/W/ 23 /g;s/X/ 24 /g;s/Y/ 25 /g;s/Z/ 26 /g"

Don't forget, you can change "with input from text" to a variable input, which will be much more useful.

Huzzah! Thanks so much. I proofread that thing a couple of times but without understanding the syntax I missed that detail. I'll play around with it now and see how I can put it to use!

Reading odd patterns like that is a skill. As I was reading your text, I was imagining music or something and I was able to spot the error as soon as I detected an anomaly in the music.

I'm also really good at spotting counterfeit money when I'm just counting a pile of money quickly.

I’d like to blame it on the Wild Turkey but in all honesty I just don't have that skillset haha.

On another note, the shell script works great to convert the letter to a numeric value... but when I try to use it to convert a number back to an alpha character it just returns the same number... am I missing something here? You mentioned in your initial reply that the reverse would be possible but I'm unsure how to adjust the script to achieve that. Sorry for the newb questions... :worried:

I have literally zero knowledge of JavaScript.... are there other advantages to using it as opposed to AppleScript or shell scripts besides what you mentioned about the unicode and local characters?

I can write the reverse for you in a minute or two. I'm not sure what your problem was since you didn't show your code. Here's the code (from A to C and Z, you need to type the other 22 pieces. :slight_smile:

sed "s/ 1 / A /g;s/ 2 / B /g;s/ 3 / C /g;s/ 26 / Z /g"

Just one thing. This code requires that there be a space at the beginning and ending of your string. This is easy to do with a KM action, and I presume you can manage that because I know you're not a newb. But I can help if you can't do that.

There are probably other shell utilities like awk that can handle this in a smarter loop, but I assure you they are far more complex to write and understand than my sed script.

Assuming I didn’t make any typos this outputs the same number that it's supplied with... did I set it up wrong?

test awk conversion.kmmacros (2.3 KB)

I'm pondering it. Give me a minute. The only thing I see wrong so far is the title, which says awk, but which should say sed.

YES, I know why, You didn't follow my advice to ensure that the string starts and stops with a space. Try this text for input:

1 2 3 4 5

it should give you: (because you don't have leading and trailing spaces)

1 B C D 5

So if you change your input to " 1 " it should work.

I can add a way to fix this for you, but I didn't want to complicate your life. Do you want me to fix it?