String - Vowels to uppercase, letters to next in alphabet - Javascript - javascript

I'm trying to convert all the letters of the string to the following letter of the alphabet, e.g. A should become B, X should become Y, Z should become A etc.
I want to capitalize every vowel after the letter shifting is done.
function LetterChanges(str) {
var c = str.split("");
var vowels = ["a", "e", "i", "o", "u"];
if (c == vowels) {
vowels.toUpperCase();}
if (c == "z") return "a";
return str.replace(/[a-z]/gi, function(s) {
return String.fromCharCode(s.charCodeAt(c)+1);
});
}
LetterChanges("cold buttz");
The vowels part and the z to a part is not working. Please help?

See if this helps:
var str = 'cold buttz';
str = str.replace(/[a-z]/gi, function(char) {
char = String.fromCharCode(char.charCodeAt(0)+1);
if (char=='{' || char=='[') char = 'a';
if (/[aeiuo]/.test(char)) char = char.toUpperCase();
return char;
});
console.log(str); //= "dpmE cvUUA"
Edit: I can see your code was sort of a messy copy/paste from my last answer... Here's a brief description of what's wrong with it:
function LetterChanges(str) {
var c = str.split(""); // array of letters from `str`
var vowels = ["a", "e", "i", "o", "u"]; // array of vowels
// `c` and `vowels` are two different objects
// so this test will always be false
if (c == vowels) {
// `toUpperCase` is a method on strings, not arrays
vowels.toUpperCase();
}
// You're comparing apples to oranges,
// or an array to a string, this test will also be false
// Then you return 'a'?? This was meant to be inside the `replace`
if (c == "z") return "a";
// OK, I see you recycled this from my other answer
// but you copy/pasted wrong... Here you're basically saying:
// "For each letter in the string do something and return something new"
return str.replace(/[a-z]/gi, function(s) { // `s` is the letter
// Here we find out the next letter but
// `c` is an array and `charCodeAt` expects an index (number)
return String.fromCharCode(s.charCodeAt(c)+1);
// `.charCodeAt(0)` gives you the code for the first letter in a string
// in this case there's only one.
});
}

My solution does exactly what you asked for. The letters are first shifted in the alphabet and then the vowels are uppercased.
Have a look:
function LetterChanges(str) {
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var ret = new Array();
for (var x=0; x < str.length; x++) {
for(var i=0; i < alphabet.length; i++) {
if (checkIfCharInString(alphabet, str[x]) == false) {
ret[x] = str[x].toString();
break;
}
if (str[x] == alphabet[i]) {
if (alphabet[i] == "Z") {
ret[x] = "A";
} else {
ret[x] = alphabet[i+1];
}
}
}
}
var output = ret.join("");
output = capitalizeVowels(output);
// code goes here
return output;
}
function checkIfCharInString(motherString, char)
{
for(var i=0; i < motherString.length; i++) {
if (motherString[i] == char.toString()) {
return true;
}
}
return false;
}
function capitalizeVowels(str)
{
var vowel = "aeiou";
var newStr = new Array();
for(var i=0; i < str.length; i++) {
for(var x=0; x < vowel.length; x++) {
newStr[i] = str[i];
if (str[i] == vowel[x]) {
newStr[i] = vowel[x].toUpperCase();
break;
}
}
}
return newStr.join("");
}
console.log(LetterChanges("Hello*3"));
console.log(LetterChanges("I love stackoverflow!"));
console.log(LetterChanges("I have Internet explorer!!"));

Related

I need help executing an if-function - My "if-function" executes, as well as my "else-function"?

Hi have this code below to check whether the first letter is a vowel or a consonant. If it is a vowel, you take the word and add "way" to the end. If it is a consonant, it moves the first letter to the end and suffixes an "ay" For some reason, when it is a vowel, it executes my else function? Any help would be appreciated. Here is my code:
function translatePigLatin(str) {
var vowels = ["a", "e", "i", "o", "u"];
for (i = 0; i < vowels.length; i++) {
if (str.charAt(0) === vowels[i]) {
return str += "way";
} else {
var first = str.charAt(0);
return str.substr(1, str.length) + first;
}
}
}
console.log( translatePigLatin("eight") );
The reason you get "ighte" instead of "eightway" is the first time your loop runs, you're comparing the first letter of the string ("e") with the first vowel in your vowels array ("a").
You can do without the for loop by using includes().
function translatePigLatin(str) {
if (["a", "e", "i", "o", "u"].includes(str.charAt(0))) {
return str += "way";
}
else {
var first = str.charAt(0);
return str.substr(1, str.length) + first;
}
}
If your intention with the for loop was to keep iterating the function until it encounters a vowel, then we can use this:
function translatePigLatin(str) {
for (var i = 0; i < str.length; i++) {
if (["a", "e", "i", "o", "u"].includes(str.charAt(i))) {
return str += "way";
}
else {
var first = str.charAt(0);
str = str.substr(1, str.length) + first;
}
}
}
This is happening because, if condition checks for 'a' as the first vowel of the word and if the character does not match it goes to else statement. Hence here rest of the vowels are not being checked, Ideal way would be to first check for all vowels and then do else part below is the code
function translatePigLatin(str) {
var vowels = ["a", "e", "i", "o", "u"];
var first = str.charAt(0);
for (i = 0; i < vowels.length; i++) {
if (first === vowels[i]) {
return str += "way";
}
}
return str.substr(1, str.length) + first;
}
console.log( translatePigLatin("eight") );
Your for loop will only ever run once as even if your first condition fails your else will be taken and therefore it will return. Consider moving the else logic from the loop.
function translatePigLatin(str) {
var vowels = ["a", "e", "i", "o", "u"];
for (i = 0; i < vowels.length; i++) {
if (str.charAt(0) === vowels[i]) {
return str += "way";
}
}
var first = str.charAt(0);
return str.substr(1, str.length) + first + "ay";
}
console.log( translatePigLatin("eight") );
Try something like this:
function translatePigLatin(str) {
var vowels = ["a", "e", "i", "o", "u"];
var firstVowel = false;
for (var i = 0; i < vowels.length; i++) {
if (str.charAt(0) === vowels[i]) {
firstVowel = true;
}
}
if (firstVowel) {
return str += "way";
} else {
var first = str.charAt(0);
return str.substr(1, str.length) + first + "ay";
}
}
console.log( translatePigLatin("eight") );
console.log( translatePigLatin("run") );

Why does this .indexOf method not work on this array?

I have the following code:
var newArr = [];
function mutation(arr) {
//Makes both values lowercase
for (var i = 0; i < arr.length; i++) {
newArr.push(arr[i].toLowerCase());
}
//splits the letters of the second value into separate values.
var letters = [];
letters.push(newArr[1]);
letters = letters.toString();
letters = letters.split('');
//checks to see if there is a letter that isn't in the first value.
for (var j = 0; j < letters.length; j++) {
if (newArr[1].indexOf(letters[j]) == -1) {
return false;
}
}
return true;
}
mutation(["voodoo", "no"]);
It works on something like (["hello", "hey"]), but it doesn't work on the method above. Why does the .indexOf method not work on this array?
I dont really know what the code should do but lets check it step by step:
var newArr = [];
function mutation(arr) {
// Makes both values lowercase
// arr is now ["voodoo", "no"]
for (var i = 0; i < arr.length; i++) {
newArr.push(arr[i].toLowerCase());
}
// newArr has the same content: ["voodoo", "no"]
//splits the letters of the second value into separate values.
var letters = [];
letters.push(newArr[1]); // letters is now ["no"]
letters = letters.toString(); // letters is now "no"
letters = letters.split(''); // letters is now ["n", "o"]
//checks to see if there is a letter that isn't in the first value.
for (var j = 0; j < letters.length; j++) { // foreach ["n", "o"]
if (newArr[1].indexOf(letters[j]) == -1) { // "no".indexOf("n") and "no".indexOf("o") is always > -1
return false; // so false is never returned
}
}
return true; // true is always returned
}
mutation(["voodoo", "no"]);
I think you should change the
if (newArr[1].indexOf(letters[j]) == -1)
to
if (newArr[0].indexOf(letters[j]) == -1)
if you want to test if one letter of the second word is not included in the first word.

Capture non-adjacent repeating letters

How do I capture repeating letters in a word like abababa = 2matches( a and b is repeating )
I know how to do it when the letters are adjacent like so /(\w)\1+/ .
Thanks
Try to use this String expansion:
String.prototype.getRepeating = function() {
var length = this.length;
var found = '';
var repeating = '';
var index;
var letter;
for (index = 0; index < length; index++) {
letter = this.charAt(index);
if (-1 == found.indexOf(letter)) {
found = found.concat(letter);
} else {
if (-1 == repeating.indexOf(letter)) {
repeating = repeating.concat(letter);
}
}
}
return repeating;
}
The tests:
var tests = ['ab', 'aa', 'bb', 'abab', 'abb', 'aab', 'bab'];
for (var index in tests) {
console.log(tests[index], '=>', tests[index].getRepeating());
}
ab => (an empty string)
aa => a
bb => b
abab => ab
abb => b
aab => a
bab => b
If I understand correctly, you want to extract letters which appear more than once in a given word. If so, you simply need to iterate over the letters of the word, accumulate their occurrence, then filter out letters which only appear once.
var testString = "abababa";
var letters = countGroupByLetter(testString);
var result = filterMap(letters, function(v) {
return v > 1;
});
console.log(result);
function countGroupByLetter(testString) {
var result = {};
for (var ii = 0; ii < testString.length; ii++) {
var letter = testString.charAt(ii);
if (result[letter]) {
result[letter] ++;
} else {
result[letter] = 1;
}
}
return result;
}
function filterMap(map, filterFunction) {
var result = {};
for (var p in map) {
if (filterFunction(map[p])) {
result[p] = map[p];
}
}
return result;
}
Since you already know about back references, I suppose that you know you can find out if there is a letter repetition in a string, using /(\w).*\1/. Capturing all repetitions in one pass would not be possible though, you'd still need to execute a pattern repeatedly and accumulate the matched characters (for instance using /(\w)(?=.*\1)/g). That, however, would not be optimal.
var repeatingLetters = /(\w)(?=.*\1)/g;
var testString = "abababa";
var captures = null;
var result = {};
while ((captures = repeatingLetters.exec(testString)) != null) {
result[captures[1]] = true;
}
console.log(result);

Returning a string with only vowels capitalized

I'd like to return the variable newString with only vowels capitalized. Not sure how to proceed. Tried using an if/else block but my logic wasn't correct.
function LetterChanges(str) {
var newArray = [];
for (var i = 0; i < str.length; i++) {
var strCode = str.charCodeAt(i) + 1;
var strLetter = String.fromCharCode(strCode);
newArray.push(strLetter);
var newString = newArray.join("");
}
return newString;
}
LetterChanges("hello");
This is different from your approach, but you can do this:
function LetterChanges(str) {
return str.toLowerCase().replace(/[aeiou]/g, function(l) {
return l.toUpperCase();
});
}
console.log(LetterChanges("The Quick Brown Fox Jumped Over The Lazy Dog"));
Here's an approach that's closer to your attempt and uses somewhat simpler concepts:
function LetterChanges(str) {
var newArray = [];
for (var i = 0; i < str.length; i++) {
var ch = str.charAt(i);
if ('aeiouAEIOU'.indexOf(ch) !== -1) {
newArray.push(ch.toUpperCase());
} else {
newArray.push(ch.toLowerCase());
}
}
return newArray.join("");
}
Split, map, join.
var vowels = 'aeiou';
var text = 'my random text with inevitable vowels';
var res = text.split('').map(function(c){
return (vowels.indexOf(c) > -1) ? c.toUpperCase() : c;
});
See the fiddle: http://jsfiddle.net/zo6j89wv/1/
Strings are Collections of word-characters, so you can directly access each part of the string:
var foo = 'bar';
console.log(foo[0]); // outputs 'b'
Hence you can extend this to uppercase the output:
console.log(foo[0].toUpperCase() // outputs 'B'
To do this without regex, you can set the string to lower case, then iterate once over, calling toUpperCase() on each vowel.
function letterChanges(string){
var vowels = 'aeiou';
var lowerString = string.toLowerCase();
var result = '';
for( var i=0; i<lowerString.length; i++){
if( vowels.indexOf( lowerString[i] ) >= 0 ){ //if lowerString[i] is a vowel
result += lowerString[i].toUpperCase();
} else {
result += lowerString[i]
}
}
return result;
}
const vowelSound = string => {
let res = string.split("").filter(item => item === 'a' || item === 'i' || item === 'e' || item === 'o' || item === 'u')
return res.join("")
}

Replace array values with new defined values in Javascript

//Get message from textarea
var msg = $('#mytextarea').val();
//Convert string to array of letters
// eg. cata = ['c','a','t','a']
var msgLettersAsArray = msg.split('');
What I need to do now is replace the single letters,something like this
c = b;
a = e;
t = c;
a = e;
//array neeeds to be converted from this:
var array = ['c','a','t','a'];
// to this:
var array = ['b','e','c','e'];
Is there any way to achieve this?
All I need to do is replace the letters that are already in the array with letters of my choice
It's quite simple, just define a translation map and use Array.prototype.map.
var translationMap = {
c: 'b',
a: 'e',
t: 'c'
};
//returns ['b','e','c','e']
['c','a','t','a'].map(function (letter) { return translationMap[letter] || letter; });
EDIT: It seems you actually just wanted to replace letters in the string, in this case #phylax answer would be correct. There is no need to use arrays for a simple string replacement.
function replaceChars(str, map) {
var i, reg = "";
for (i in map)
reg += i;
return str.replace(
new RegExp("["+reg.replace(/(\]|-|\\)/,"\\$1")+"]",'g'),
function(char) { return map[char]; }
);
}
//Get message from textarea
var msg = $('#mytextarea').val(); // "cata"
replaceChars(msg, {c:'b', a:'e', t:'c', a:'e'}); // "bece"
Just making an answer out of my comment:
Like OP said, its ok to be done without the split(). And its possible to do with only one call to String.replace():
var map = {
c: 'b',
a: 'e',
t: 'c'
};
msg.replace(/[a-z0-9]/g, function (i) { return map[i] || i; })
The RegExp can possibly made event simpler:
msg.replace(/./g, function (i) { return map[i] || i; })
Sure, just use a for loop:
var array = ['c','a','t','a'];
for (var i = 0; i < array.length; i++)
{
var cur = array[i];
if (cur == 'c') {
array[i] = 'b';
} else if (cur == 'a') {
array[i] = 't';
} else if (cur == 't') {
array[i] = 'c';
}
}
But using an object to store these mappings can make your code even more compact:
var array = ['c','a','t','a'];
var transform = { 'c': 'b', 'a': 'e', 't': 'c' };
for (var i = 0; i < array.length; i++)
{
array[i] = transform[array[i]];
}
not tested but it should work
var replaxe = {
'c':'b',
'e':'d'
},
array = ['c','e'],
result = [];
for(var item in array){
result.push(replaxe[item]);
}
console.log(result);
RUN THIS IN YOUR FIRE BUG CONSOLE
var array = ['c','a','t','a'];
var myarray = [];
for(i=0; i<=array.length; i++)
{
if(array[i] == 'c' )
{
array[i] = 'b'
}
if(array[i] == 'a' )
{
array[i] = 'e'
}
if(array[i] == 't' )
{
array[i] = 'c'
}
if(array[i] == 'a' )
{
array[i] = 'a'
}
}
console.log(myarray);
I would recommend using a switch-case for every element in the array.
for (i in array) {
switch (array[i]) {
case "c":
array[i] = "b";
break;
case "a":
array[i] = "e";
break;
case "t":
array[i] = "c";
break;
}
}

Categories