Reverse vowels in a string, using regex - javascript

I am working on an algorithm that takes in a string for input, and reverses the vowels of the string.
'hello' should return as 'holle'
'wookiE' should return as 'wEikoo'
Could str.replace be used as a solution?
function reverseVowels(str) {
return str.replace(/[aeiou]/-g, /[aeiou]+1/);
}
I am not sure what the second parameter for the replace function would be. I intended to find the first vowel and then move on to the next one to replace it with. Can this be done just with this method or is a forEach/for loop needed?

You could do this in two phases:
extract the vowels into an array
perform the replace on the original string, calling a function on each match and popping the last vowel from the stack to replace it.
Code:
function reverseVowels(str){
var vowels = str.match(/[aeiou]/g);
return str.replace(/[aeiou]/g, () => vowels.pop());
}
// example
var original = 'James Bond';
var result = reverseVowels(original);
// output for snippet
console.log(original + ' => ' + result);

Related

string replace with return statement gives different result. need the clarity

Case 1 : replace with function return results j<*zz
const str = 'z<*zj';
const letters = Array.from(str.replace(/[^a-zA-Z]/gm, ''));
const result = str.replace(/[a-zA-Z]/gm, () => letters.pop());
console.log('result', result); // result => j<*zz/
Case 2 : replace without function return results j<*jj
const str = 'z<*zj';
const letters = Array.from(str.replace(/[^a-zA-Z]/gm, ''));
const result = str.replace(/[a-zA-Z]/gm, letters.pop());
console.log('result', result); // result => j<*jj/
So, It differs with function integration. what is behind ? Need the help to understand.
As per the documentation, If a replacement parameter is a function, it will be invoked for every match and its return value is used as the replacement text.
Hence, In case 1 as we are passing replacement as an arrow function, it executes for each match and replace with the letters array last element. As we are using Array.pop() method, It changes the length of the original array and returns the last element.
For example,
const str = 'z<*zj';
const letters = Array.from(str.replace(/[^a-zA-Z]/gm, ''));
console.log(letters.pop()); // j
console.log(letters); // ["z", "z"]
In this case, in second iteration it will pop the z and replaced with the matched value.
Now if we will talk about the case 2, As replacement parameter is a string, It will replace the substring matched by pattern in a single go.
For example,
const str = 'z<*zj';
const arr = ['z', 'z', 'j'];
const result = str.replace(/[a-zA-Z]/g, arr.pop());
console.log(result);
There exists an overload for String.prototype.replace that accepts a function. This function will execute on every match. Each match then mutates letters via the pop method.
When you use letters.pop() instead of a method that returns letters.pop(), it is only executed once and its result is reused for each match.
Since the last letter in letters is j, letters.pop() evaulates to j and each letter is replaced with j.
When using the function variant, the last letter is j, so the first letter is replaced with j, but for subsequent matches, we're now popping from a mutated array, so we then return z and finally z.

a bit clarafication on using spread and string manipulation, foreach loop

so I've wrote this function, i want to uppercase the vowels and lowercase every other letter,
problem the end result ends with the same string, I'm new to spread and for-each,
after i spread a string does it become an array?
when i manipulate letters does it suppose to become a string again with the manipulations or do i need to join it? why aren't the upper and lowercase functions don't work?
the function:
function upperCase(str) {
var vowels = "aeiou";
[...str].forEach(letter => {
if (vowels.includes(letter)) letter.toUpperCase();
letter.toLowerCase();
});
console.log(str);
}
You have several problems:
.toUpperCase and toLowerCase return the new value, they don't mutate the existing value (and strings are immutable anyway)
Even if they did mutate the existing value, they'd change the letter string in the array and not the original string
You didn't use else to toLowerCase always runs
You need to:
return a value
Use map to collect the values
Use join() to turn the array back into a string
Such:
function upperCase(str) {
const vowels = "aeiou";
const result =
[...str]
.map(
letter =>
(vowels.includes(letter))
? letter.toUpperCase()
: letter.toLowerCase()
).join("");
console.log(result);
}
upperCase("The quick brown fox jumps over the lazy dog");
You need to assign the result of your foreach to something.
function upperCase(str) {
var vowels = "aeiou";
[...str].forEach(letter => {
if (vowels.includes(letter)) letter.toUpperCase();
letter.toLowerCase();
});
console.log(str);
}
[...str] is creating an array, looping over it, preforming an action, but then not saving the resulting array to any variable at the end. You're also missing an else and/ or a return. I think a map also makes more sense in this case.
function upperCase(str) {
var vowels = "aeiou";
const result = [...str].map(letter => {
if (vowels.includes(letter)) return letter.toUpperCase();
return letter.toLowerCase();
});
console.log(result);
}
If you just want to manipulate a string you might want to use the replace function
const newString = str.toLowerCase().replace(/[a,e,i,o,u]/g, letter => letter.toUpperCase())
This first puts everything to lower case, and afterwards replaces all vowels (matching the regular expression) by their upper case versions.

Remove all consonants in a string before a vowel then add a character

I want to remove all consonants in a string before the occurrence of a vowel and then replace it with an 'r'.
This means that 'scooby' will become 'rooby', 'xylographer' will become 'rographer' and so on. This is the algorithm I came up with:
1. Check if input type is not a string.
2. Use a variable(newStr) to hold lowercase conversion and splitted word.
3. Declare a variable(arrWord) to hold the length of the array.
4. Another variable called regex to check if a string starts with a consonant
5. Variable newArr holds the final result.
6. Search through the array, if the string does not start with a consonant
join it and return it.
7. Else keep looking for where the first vowel occurs in the word.
8. When found, remove all characters(consonants) before the vowel occurence
and replace them with an r.
9. Join the array together.
I have been able to come up with this:
const scoobyDoo = str => {
if(typeof str !== 'string'){
return 'This function accepts strings only';
}
let newStr = str.toLowerCase().split('');
let arrWord = newStr.length;
let regex = /[aeiou]/gi;
for (let i = 0; i < arrWord; i++){
if (newStr[0].match(regex)) {
let nothing = newStr.join('');
return nothing;
}
else {
let vowelIndex = newStr.indexOf(str.match(regex)[0]);
newStr.splice(0, vowelIndex, 'r');
return newStr.join('');
}
}
}
console.log(scoobyDoo('scOoby'));
I tested out the program again by capitalizing the first vowel index and instead of 'rooby' I get 'rscooby'. Why is that so?
Can you once try with following code in your else and see the changes
else {
var vowelIndex = newStr.indexOf(str.match(regex)[0]);
newStr.splice(0, vowelIndex, 'r');
return newStr.join("");
}
Is it not much easier like this? Or am I missing something??
'xylographer'.replace(/^\s*[^aieou]+(?=\w)/i,function(m,o,s){return "r"})
//"rographer"
'scooby'.replace(/^\s*[^aieou]+(?=\w)/i,function(m,o,s){return "r"})
//"rooby"
you could just use one reg expression for the whole algorithm and no need to split your string no more.
regexp to use.
/^[^aouie, AOUIE]+(?=[aouie, AOUIE])/g
of course you can readjust regexp to suit you more but this will get your main requirement.
On the line immediately after the else statement, I just called .toLowerCase() on it and it was fixed:
let vowelIndex = newStr.indexOf(str.match(regex)[0].toLowerCase());
I like keeping my code simple and readable
function pattern(str){
var vowelIndex = str.indexOf(str.match(/[aeiou]/)); //returns index of first vowel in str
return "r" + str.slice(vowelIndex);
}
console.log(pattern('xylographer'));

How to replace all occurrences between two specific characters with the associated char Code using reqex?

I'd like to replace everything between two characters with another string. I came up with this function:
String.prototype.unformat = function() {
var s='';
for (var i=0; i<this.length;i++) s+=this[i]
return s.replace(/\$[^$]*\$/g, '')
};
Using a string like 'This is a test $33$' and unformat it with the function above, it will return 'This is a test '.
Ok-cool, but I'd like to replace all occurrences in ( $ ... $ ) with the associated char code.
In the example 'This is a test $33$', I like to replace $33$ with the result of the javascript String.fromCharCode() function to get the string 'This is a test !' as result.
How to edit the prototype function above to get the desired result?
Thanks in advance :)
You can use a callback function that returns fromCharCode() with the matched code
String.prototype.unformat = function() {
return this.replace(/\$([^$]*)\$/g, function (string, charcode) {
return String.fromCharCode(charcode);
});
};
console.log(("char: $33$").unformat());
In order to avoid any future problems, I would also adapt the regex to only match digits: /\$(\d+)\$/g
You can use a match group () and replace it with the String.fromCharCode result:
String.prototype.unformat = function() {
return this.replace(/\$(.*?)\$/g, function(match, group) { // the match is the whole match (including the $s), group is the matched group (the thing between the $s)
return String.fromCharCode(group);
});
};
Notes:
No need to copy the string as replace doesn't mutate the original string (this).
The match group (.*?) is a non-greedy one (lazy one) that matches as few characters as possible.
It is better if you don't mess around natives' prototypes (such as String, Number, ...).
Example:
String.prototype.unformat = function() {
return this.replace(/\$(.*?)\$/g, function(match, group) {
return String.fromCharCode(group);
});
};
console.log('This is a test $33$'.unformat());

make a string alphabetical order using only javascript

I want to make a string in alphabet order using javascript.
example, if string is "bobby bca" then it must be "abbbbcoy" but I want it in a function - take not that I dont want spaces to be there just alphabet order.
I'm new to javascript here is what I have already:
function make Alphabet(str) {
var arr = str.split(''),
alpha = arr.sort();
return alpha.join('');
}
console.log(Alphabet("dryhczwa test hello"));
There are a few things wrong with this code as the comments under your post mentioned.
the function name is incorrect, it has to be one word as well as the same as when you calling it to actually use the function.
once that is out the way then your code is correct and actually makes things alphabetical
About the spaces you want removed then you can use regex inside the function to remove the spaces and make it output just the characters in alphabetical order like this:
function makeAlphabet(str) {
var arr = str.split(''),
alpha = arr.sort().join('').replace(/\s+/g, '');
return alpha;
}
console.log(makeAlphabet("dryhczwa test hello"));
Other than that this is what I could make of your question
This is updated based on the comment and here is the fiddle: https://jsfiddle.net/ToreanJoel/s2j68s4s/
you start from a string like
var str ='dryhczwa test hello';
create an array from this
var arr = str.split(' ');
then you sort it (alphabetically)
var array = arr.sort();
and you join it back together
var str2 = array.join(' ');
fiddle
Your function name cannot have spaces;
function makeAlphabet(str) {
return str.split('').sort().join('');
}
Plus, this won't remove spaces, so your example
console.log(makeAlphabet("dryhczwa test hello"));
Will return ' acdeehhllorsttwyz'.
The function:
function makeAlphabet(str) {
var arr = str.split('');
arr.sort();
return arr.join('').trim();
}
An example call:
console.log(makeAlphabet("dryhczwa test hello"));
// returns "acdeehhllorsttwyz"
Explanation:
Line 1 of makeAlphabet converts the string into an array, with each character beeing one array element.
Line 2 sorts the array in alphabetic order.
Line 3 converted the array elements back to a string and thereby removes all whitespace characters.

Categories

Resources