Estoy tratando de aprender el método forEach() pero no puedo encontrar ejemplos más avanzados. Así que pensé en refactorizar mi código de Codewars para aprender de él. No sé cómo usar correctamente el método forEach en bucles anidados. Espero que puedas ayudarme a aprender de este ejemplo :)
6 kyu: reemplazar con la posición alfabética https://www.codewars.com/kata/546f922b54af40e1e90001da/train/javascript
function alphabetPosition(text) { let textToArray = text.replace(/[^a-zA-Z]/gi,'').toUpperCase().split(''); //Eliminate anything thats not a letter const 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"]; let pointsHolder = []; //empty array for score for (let i = 0; i < textToArray.length; i++){ for (let j = 0; j < alphabet.length; j++) { if (textToArray[i] == alphabet[j] ) { //We check the index of given string letter in alphabet pointsHolder.push(j+1) //give it a score based on place in alphabet(+1 for 0 as 1st index) } } } return pointsHolder.join(' '); //return scored array as a string with spaces }Realmente no hay necesidad de usar un bucle anidado, que es computacionalmente costoso. Con eso, tampoco tiene que crear manualmente una matriz AZ.
Puede convertir fácilmente alfabetos a cualquier número arbitrario usando String.charCodeAt() . a tiene un código de carácter de 97, b tiene un código de carácter de 98, y etc... para obtener un índice basado en uno (a=1, b=2, ...) solo necesita restar 96 del número.
function alphabetPosition(text) { const alphabets = text.toLowerCase().replace(/[^az]/g, '').split(''); return alphabets.map(alphabet => alphabet.charCodeAt(0) - 96).join(' '); } Alternativamente, también puede usar un bucle for...of , pero eso requiere almacenar la matriz en otra variable antes de devolverla:
function alphabetPosition(text) { const alphabets = text.toLowerCase().replace(/[^az]/g, ''); const codes = []; for (const alphabet of alphabets) { codes.push(alphabet.charCodeAt() - 96); } return codes.join(' '); }(Nota: la solución de @Terry sigue siendo la solución más eficiente para su desafío de código)
Puede reemplazarlo de la siguiente manera:
function alphabetPosition(text) { let textToArray = text.replace(/[^a-zA-Z]/gi, '').toUpperCase().split(''); const 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"]; let pointsHolder = []; textToArray.forEach(t2a => { alphabet.forEach((a, j) => { if (t2a == a) { pointsHolder.push(j + 1) } }) }) return pointsHolder.join(' '); } console.log(alphabetPosition("ABCSTU"))Una alternativa a la solución charCode propuesta en la respuesta de Terry, pero que también evita los bucles anidados, es crear un Map de los caracteres con los que desea puntuar y luego acceder a él por carácter desde la cadena pasada.
Tenga en cuenta que las cadenas son iterables sin necesidad de convertirlas en una matriz.
function alphabetPosition(text) { text = text.toUpperCase().replace(/[^AZ]/gi, ''); const alphabet = new Map( ["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"] .map((v, i) => [v, i + 1]) ); const pointsHolder = []; for (const char of text) { pointsHolder.push(alphabet.get(char)) } return pointsHolder.join(' '); } console.log(alphabetPosition("AB😬CS🐹TU"))Esto también le permite usar un Mapa que no necesariamente tiene códigos de caracteres consecutivos
function alphabetPosition(text) { text = text.toUpperCase().replace(/[^😬🐹🤓]/gi, ''); const alphabet = new Map( ["😬", "🐹", "🤓"] .map((v, i) => [v, i + 1]) ); const pointsHolder = []; for (const char of text) { pointsHolder.push(alphabet.get(char)) } return pointsHolder.join(' '); } console.log(alphabetPosition("AB😬CS🐹TU"))