You said the string "faebcd"
must become "615234"
. But what if the string is "klm"
, then she becomes "111213"
(After all, "k", "l" and "m" are respectively the 11th, 12th and 13th letters of the alphabet)? To keep things simple, let’s assume that’s it. I’m also assuming other premises:
- let’s consider only letters from A to Z (i.e., spaces, punctuation, digits, etc., all these will be ignored). I’ll also disregard accented letters.
- it is not clear what you do with characters other than letters. In the code below, I will assume that the corresponding code is zero.
- I’ll do the algorithm case insensitive: considers that both "A" and "a" will have the value 1, "B" and "b" will have the value 2, etc (one of the answers does not take this into account, so the letter "B" ends up having the value zero - I don’t know if that’s what you wanted, but anyway)
The other answers use a loop by the characters of the string, and within this loop use indexOf
or map
to check the position of the letter in the alphabet. So far so good, it works, but what you don’t realize is that these codes are creating a variation of the so-called Shlemiel the Painter’s Algorithm.
Basically, for each letter of the string, indexOf
and map
traverse the string (or array) alfabeto
to check the position of the letter in it. That is, if the phrase is "Birulei Nau", for the letter "B", the alphabet is checked from the letter "a" (and if we do not consider the algorithm case insensitive, it will go through the whole alphabet, because it will not find the "B"). Then for the letter "i", check the alphabet again, starting from "a", then to the letter "r" same thing, and so on. At the end, the alfabeto
is traversed several times (of course most of the time it will not be fully traversed, but even so are too many iterations for nothing, especially if the string has several characters that are not letters).
Anyway, another way of doing it would be:
let frase = "Birulei Nau";
let posicoes = [];
for (let i = 0; i < frase.length; i++) {
let c = frase.codePointAt(i);
// se for letra maiúscula, converte para minúscula
if (65 <= c && c <= 90) c+= 32;
if (97 <= c && c <= 122) {
posicoes.push(c - 96);
} else {
posicoes.push(0); // não é letra de A a Z, usar zero
}
}
console.log(posicoes.join(''));
I use codePointAt
to obtain the value of code point of each character (to understand what this is, read here). To simplify, the letters from A to Z have code points with the same values as the ascii table, then we can take these values and manipulate them in a "smart" way to do what we need.
The capital letters are in the range between 65 and 90, and in this case just add 32 to get the respective lowercase letter (which in turn are in the range between 97 and 122, and so just subtract 96 to get the respective position of this in the alphabet). If you want the algorithm not to be case insensitive, just remove the first if
.
Remember that I am considering that when the character is not a letter, I put the value zero. But if you want to ignore these characters, just remove the block else
.
In the above case I used an array to store the positions and then joined everything with join
. But you could also create a string directly and concatenate everything directly into it:
let frase = "Birulei Nau";
let posicoes = '';
for (let i = 0; i < frase.length; i++) {
let c = frase.codePointAt(i);
// se for letra maiúscula, converte para minúscula
if (65 <= c && c <= 90) c+= 32;
if (97 <= c && c <= 122) {
posicoes += (c - 96);
} else {
posicoes += 0; // não é letra de A a Z, usar zero
}
}
console.log(posicoes);
I did some tests and the above solutions proved faster than using indexOf
. Of course, for a few small strings the difference will be insignificant, and maybe all this is just micro-optimization, but the alternative is there anyway.
Okay, I think I get it. I’m going to test these codes. Thank you Jeanextreme002!
– Gabriel Moura