'Reverse each word with uppercase without changing word
How do I reverse each uppercase and lowercase ("I am A Great human") to ("I ma A Taerg namuh")? This is the code I Have:
function wordsReverse(str) {
let words = [];
words = str.match(/\S+./g);
let result = "";
for (let i = 0; i < words.length; i++){
result += words[i].split('').reverse().join('') + " ";
}
return result;
}
console.log(wordsReverse("I am A Great human"));
// Logs "I ma A taerG namuh"
Instead of getting "I ma A taerG namuh"
I am looking for this: "I ma A Taerg namuh"
Solution 1:[1]
One way would be to track the indices of the uppercase characters in the original word, and when reversing the word use those previous index values to uppercase the character.
If the index doesn't match a previously uppercase character, then always return it as lower case (even if it is already lower case, this won't have an effect).
function wordReverse(str) {
let reversed = [];
let words = str.split(" ");
for (let word of words) {
// Calculate which indices in the word are uppercase,
// storing in an object for faster lookups
let uppercaseIndices = word.split("").reduce((acc, char, i) => {
if (/[A-Z]/.test(char)) {
acc[i] = true;
}
return acc;
}, {});
let newWord = word
.split("")
.reverse()
.map((char, i) => {
if (uppercaseIndices[i]) {
return char.toUpperCase();
} else {
return char.toLowerCase();
}
})
.join("");
reversed.push(newWord);
}
return reversed.join(" ");
}
console.log(wordReverse("I am A Great human"));
Solution 2:[2]
function wordsReverse(str) {
let indexes = [];
let words = str.split(" ");
let result = "";
// reverse passed string
words.forEach((e) => {
result += e.split("").reverse().join("") + " ";
});
// get indexes of uppercase letters passed in function
str.split("").forEach((e, i) => {
if (e === e.toUpperCase() && e !== " ") {
indexes.push(i);
}
});
// lowercase whole string
result = result.trim().toLowerCase().split("");
// uppercase letters accordingly to indexes we get from index array
result.forEach((e, i) => {
if (indexes.includes(i)) {
result.splice(i, 1, e.toUpperCase());
}
});
return result.join("");
}
console.log(wordsReverse("I am A Great human"));
Solution 3:[3]
You can split the string into words and test each one by one with Array#map
and also split each word into letters and test each letter using Array#map
as in this quick demo:
const wordsReverse = str => str.split(' ').map(
word =>
word.split('').reverse()
.map(
(letter, i, arr) =>
arr[arr.length - i - 1].toUpperCase() === arr[arr.length - i - 1] ?
letter.toUpperCase() :
arr[arr.length - i - 1].toLowerCase() === arr[arr.length - i - 1] ?
letter.toLowerCase() :
letter
)
.join('')
)
.join(' ');
console.log(wordsReverse("I am A Great human"));
//OUTPUT: I ma A Taerg namuh
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | romellem |
Solution 2 | sanodzeg |
Solution 3 |