Reputation: 566
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
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
Reputation: 5122
There are already a lot of answers here, but it looked fun so here is my solution explained:
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
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
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
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
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
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
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