Aci
Aci

Reputation: 566

Javascript reverse alphabet

so I've been messing around with the .replace() function lately and wanted to make it reverse whatever the user inputs. (Aka a -> z, A -> Z, b -> y, B -> Y, ...)

I'm using function stacking, so I just added .replace().replace()... for every letter, but of course that won't work since whenever it hits n, it will begin to reverse all the progress and I end up with an inaccurate translation. Any idea how I can work around this, since as far as I know, JS doesn't have a .reverse() function like Python?

In case you need it, here's my code

//replacing letters
lettertext = ttext.replace("a", "z")
.replace("A", "Z")
.replace("b", "y")
.replace("B", "y")
.replace("c", "x")
.replace("C", "X")
.replace("d", "w")
.replace("D", "W")
.replace("e", "v")
.replace("E", "V")
.replace("f", "u")
.replace("F", "U")
.replace("g", "t")
.replace("G", "T")
.replace("h", "s")
.replace("H", "S")
.replace("i", "r")
.replace("I", "R")
.replace("j", "q")
.replace("J", "Q")
.replace("k", "p")
.replace("K", "P")
.replace("l", "o")
.replace("L", "O")
.replace("m", "n")
.replace("M", "N")
.replace("n", "m")
.replace("N", "M")
.replace("o", "l")
.replace("O", "L")
.replace("p", "k")
.replace("P", "K")
.replace("q", "j")
.replace("Q", "J")
.replace("r", "i")
.replace("R", "I")
.replace("s", "h")
.replace("S", "H")
.replace("t", "g")
.replace("T", "G")
.replace("u", "f")
.replace("U", "F")
.replace("v", "e")
.replace("V", "E")
.replace("w", "d")
.replace("W", "D")
.replace("x", "c")
.replace("X", "C")
.replace("y", "b")
.replace("Y", "B")
.replace("z", "a")
.replace("Z", "A")
.replace("ä", "ß")
.replace("Ä", "ẞ")
.replace("ö", "ü")
.replace("Ö", "Ü")
.replace("ü", "ö")
.replace("Ü", "Ö")
.replace("ß", "ä")
.replace("ẞ", "Ä")

Upvotes: 4

Views: 3555

Answers (8)

AndrewL64
AndrewL64

Reputation: 16331

Just create an array consisting of string characters from a - z and another array consisting of all the 8 umlaut characters that you mentioned.

You can now simply create a reusable function say, reverseChar() that accepts a character as a parameter.

The function can then check if the inputted character is an alphabet or an umlaut character using a basic regex tester.

The function then tries to match the inputted character with the string characters from the respective array and if there is a match, return the same indexed character from the array reversed.


Try inputting any character from a-z, A-Z or one of the umlaut characters mentioned above in the code snippet below to see how it works:

var alpha = ["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"];
var umlauts = ["ä","Ä","ö","Ö","ü","Ü","ß","ẞ"]

var val = "";

var result = document.getElementById("result");

function reverseChar(x) {
    
    if (/^[a-zA-Z]+$/.test(x)) {
      for (i = 0; i < 26; i++) {
          if (x.toLowerCase() == alpha[i]) {
              if (x == x.toUpperCase()) {
                val = ((alpha.reverse())[i]).toUpperCase();
              } else {
                val = (alpha.reverse())[i];
              }
          }
      }
	  result.innerHTML = `The reversed character for <strong>${x}</strong> is <strong>${val}</strong>`;
    } else {
        for (i = 0; i < umlauts.length; i++) {
        	if (x == umlauts[i]) {
            val = (umlauts.reverse())[i];
          }
        }
        result.innerHTML = `The reversed character for <strong>${x}</strong> is <strong>${val}</strong>`;
    }
}

// JavaScript below is for the HTML Example

var btn = document.getElementById("btn");

function checkChar(){
    var char = document.getElementById("char");
    var input = char.value;
    reverseChar(input);
}

btn.addEventListener("click", checkChar);
<input id="char" type="text" maxlength="1" />
<button type="button" id="btn">Check reversed character</button>
<p id="result"></p>

Upvotes: 3

Wimanicesir
Wimanicesir

Reputation: 5122

There are already a lot of answers here, but it looked fun so here is my solution explained:

  1. Split the alphabet into first part & second part
  2. Reverse the second part
  3. Check every letter in which part it is and replace it by same index but reversed of the other part
  4. Add each letter to solution

EDIT: If you want to to complete sentences, also check on space :)

var alphabet = 'abcdefghijklmnopqrstuvwxyz';
var firstpart = alphabet.substring(0,13).split('');
var secondpart = alphabet.substring(13).split('').reverse();
var button = document.getElementById("button");
var solution = '';

// Click function
button.onclick = function() {
var b = document.getElementById("text").value.split('');
// Loop every letter of input
for (var i = 0 ; i < b.length; i++) {
 if (firstpart.indexOf(b[i]) !== -1) {
   solution += secondpart[firstpart.indexOf(b[i])];
 } else {
   solution += firstpart[secondpart.indexOf(b[i])];
  }
}
console.log(solution);
// Reset solution
solution = '';
}
<input type="text" id='text'>
<button type='button'id='button'>Reverse</button>

Upvotes: 1

Tarreq
Tarreq

Reputation: 1365

Easiest way is to use built in functions, split, reverse, and join

function reverseString(str) {

    // Step 1. Use the split() method to return a new array ["h", "e", "l", "l", "o"]
    var splitString = str.split(""); 


    // Step 2. Use the reverse() method to reverse the new created array
    // will look like ["o", "l", "l", "e", "h"]
    var reverseArray = splitString.reverse(); 

    // Step 3. Use the join() method to join all elements of the array into a string
    // will look like "olleh"
    var joinArray = reverseArray.join(""); 


    //Step 4. Return the reversed string
    return joinArray; // "olleh"
}

reverseString("hello");

Upvotes: 1

FK82
FK82

Reputation: 5075

Replace won't work in this case because—as you already noticed—it will not track which letters have been replaced by a prior replace operation. So, a sequence of replace operations such as

//...
.replace("M", "N")
//...
.replace("N", "M")
//...

will just undo itself (if no replacement on substrings "N" takes place in the meantime).

You can however just map over the string as an array and then work on the ASCII/UTF8 encoding of the characters to reverse the alphabetic sequence.

const s = "AzByCx";

const f = (string) => Array.from(string)
  .map(c => {
      const code = c.charCodeAt(0);

      // Leave characters `c` outside the character set [a-zA-Z] unchanged.
      if (code < 0x41 || (code > 0x5A && code < 0x61) || code > 0x7A) { 
          return c;
      }
      
      // Compute offset to last character in the set [a-z] (ASCII/UTF8: 0x41-0x5A) respectively [A-Z] (ASCII/UTF8: 0x61-0x7A)
      let offset;
      let base;
      if (code <= 0x5A) {
          offset = 0x5A - code;
          base = 0x41;
      } else {
         offset = 0x7A - code;
         base = 0x61;
      }

      // Compute new character encoding and convert back to string.
      return String.fromCharCode(base + offset)
  })
  .join('');

console.log(`${s} ~> ${f(s)}`);
console.log(`${f(s)} ~> ${f(f(s))}`);

You can extend this to include Umlauts using the same approach.

Upvotes: 2

brk
brk

Reputation: 50346

Create an object where key will be the letters of the string and its value will be the character which with you want to replace.

The on getting the input value split the string and create an array and use map and inside it's callback function check for the case of the character.

If it is lower case then directly retrieve the value, if upper case convert it to lower case to get the value from dictionary object and then convert it back to uppercase before returning.

Use join to create the final string

let rvObj = {
  a: 'z',
  b: 'y'
}

function reverse() {
  var b = document.getElementById("text")
    .value //get value of input
    .trim() // remove whitespace
    .split("") // create an array
    .map(function(a) { //map will return new array
      return a === a.toLowerCase() ? rvObj[a] : rvObj[a.toLowerCase()].toUpperCase();
    }).join(""); // create a string from the array
  console.log(b);
};
<input type="text" id='text'>
<button type='button' onclick='reverse()'>Reverse</button>

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386826

You could take a hash table for the pairs and map new character or the original character if not available in the hash table.

function replace(string) {
    var code = { "a": "z", "A": "Z", "b": "y", "B": "y", "c": "x", "C": "X", "d": "w", "D": "W", "e": "v", "E": "V", "f": "u", "F": "U", "g": "t", "G": "T", "h": "s", "H": "S", "i": "r", "I": "R", "j": "q", "J": "Q", "k": "p", "K": "P", "l": "o", "L": "O", "m": "n", "M": "N", "n": "m", "N": "M", "o": "l", "O": "L", "p": "k", "P": "K", "q": "j", "Q": "J", "r": "i", "R": "I", "s": "h", "S": "H", "t": "g", "T": "G", "u": "f", "U": "F", "v": "e", "V": "E", "w": "d", "W": "D", "x": "c", "X": "C", "y": "b", "Y": "B", "z": "a", "Z": "A", "ä": "ß", "Ä": "ẞ", "ö": "ü", "Ö": "Ü", "ü": "ö", "Ü": "Ö", "ß": "ä", "ẞ": "Ä" };
    return Array.from(string, c => code[c] || c).join('');
}

console.log(replace('Übermut2019')); // 'Öyvinfg2019'
console.log(replace('Öyvinfg2019')); // 'Übermut2019'

Upvotes: 2

Aminadav Glickshtein
Aminadav Glickshtein

Reputation: 24630

Insted of using all the replace statments, you can use the char code, to automatically find the matching pair:

a='abcxyzABC'.replace(/./g,function(letter){
if (letter>='a' && letter<='z') {
    return String.fromCharCode( 'z'.charCodeAt(0) - letter.charCodeAt(0) + 'a'.charCodeAt(0)  )
}
if (letter>='A' && letter<='Z') {
    return String.fromCharCode( 'Z'.charCodeAt(0) - letter.charCodeAt(0) + 'A'.charCodeAt(0)  )
}
})

//ouptut: 'zyxcbaZYX"

Upvotes: 1

Aminadav Glickshtein
Aminadav Glickshtein

Reputation: 24630

You have to switch every letter only once. You can use this pattern:

a='abcxyz'.replace(/./g,function(letter){
switch (letter) {
        case 'a':
            return 'z'
    default:
        return letter
}
})

What we doing, It will replace a to z. But it will not replace it again to a. Every letter is replaced only once.

The function I used for the replace, is executed on every letter in the string.

Upvotes: 1

Related Questions