The question is :
Using the JavaScript, have the function LetterChanges(str) take the str parameter being passed and modify it using the following algorithm. Replace every letter in the string with the letter following it in the alphabet (ie. c becomes d, z becomes a). Then capitalize every vowel in this new string (a, e, i, o, u) and finally return this modified string.
function LetterChanges(str){
var result = "";
for(var i = 0; i < str.length; i++) {
var letters = str[i];
if (letters == "a"|| letters == "e"|| letters == "i"|| letters == "o"|| letters =="u") {
letters = letters.toUpperCase();
result+=letters;
} else if (letters == "z") {
letters = "a";
} else {
var answer = "";
var realanswer="";
for (var i =0;i<str.length;i++) {
answer += (String.fromCharCode(str.charCodeAt(i)+1));
}
realanswer += answer
}
}
return realanswer;
return result;
}
LetterChanges();
basically, if return realanswer is placed before return result and LetterChanges is called with "o" i get the output undefined. But if it is called with a non vowel such as "b" it will output "c" which is correct.
now if i place return result before return realanswer it will work properly for vowels but not for other letters. thanks for the help
function LetterChanges(str) {
return str
.replace(/[a-zA-Z]/g, (x) => String.fromCharCode(x.charCodeAt(0)+1))
.replace(/[aeiou]/g, (v) => v.toUpperCase());
}
The first part modifies the consonants by an increment of 1.
Regex is isolating the characters with [] versus no brackets at all. g ensures that the regex is applied anywhere in the string, as opposed to not putting g which gives you the first occurrence of the search.
You have to convert the characters in the string to their Unicode because incrementing is a math operation. x.charCodeAt(0) is saying at the index of 0 of the string in the argument. The increment of 1 is not within the parentheses but outside.
The second part modifies the vowels to upper case.
This is pretty straightforward, the regex only finds the individual characters because [] are used, g for anywhere in the string. and the modifier is to make the characters become upper case.
function LetterChanges(str) {
var lstr = "";// Took a variable to store after changing alphabet//
for(var i=0;i<str.length;i++){
var asVal = (str.charCodeAt(i)+1);// To convert string to Ascii value and 1 to it//
lstr += (String.fromCharCode(asVal));// To convert back to string from Asii value//
}
console.log("Before converting vowels :"+lstr); //Printing in console changed alphabet//
var neword =""; // variable to store word after changing vowels to uppercase//
for(i=0;i<lstr.length;i++){
var strng = lstr[i]; // Storing every letter in strng variable while running loop //
if(strng=="a"||strng=="e"||strng=="i"||strng=="o"||strng=="u"){
neword += strng.toUpperCase(); // If it a vowel it gets uppercased and added //
}
else{
neword += strng; // If not vowel , it just gets added without Uppercase //
}
}
console.log("After converting vowels :"+neword); //Printing in console the word after captilising the vowels //
}
LetterChanges("Goutham"); // Calling a function with string Goutham //
function letterChanges(str) {
let res = '';
let arr = str.toLowerCase().split('');
// Iterate through loop
for(let i = 0; i < str.length; i++) {
// Convert String into ASCII value and add 1
let temp = str.charCodeAt(i) + 1;
// Convert ASCII value back into String to the result
res += (String.fromCharCode(temp));
}
console.log(res);
// Replace only vowel characters to Uppercase using callback in the replace function
return res.replace(/[aeiou]/g, (letters) {
return letters.toUpperCase();
});
}
function LetterChanges(str) {
return str
.split('')
.map((c) => String.fromCharCode((c >= 'a' && c <= 'z') ? (c.charCodeAt(0)-97+1)%26+97 : (c >= 'A' && c <= 'Z') ? (c.charCodeAt(0)+1-65)%26+65 : c.charCodeAt(0)))
.join('').replace(/[aeiou]/g, (letters) => letters.toUpperCase());
}
export const letterChange=(str)=>{
let newStr = str.toLowerCase().replace(/[a-z]/gi, (char)=>{
if(char==="z"){
return "a"
}else{
return String.fromCharCode(char.charCodeAt()+1)
}
})
let wordCap = newStr.replace(/a|e|i|o|u/gi, char => char.toUpperCase())
return wordCap
}
function changeLetters(str) {
var result = "";
for (var i = 0; i < str.length; i++) {
var item = str[i];
if (
item == "a" ||
item == "e" ||
item == "i" ||
item == "o" ||
item == "u"
) {
item = item.toUpperCase();
result += item;
} else if (item == "z") {
letters = "a";
result += item;
} else {
result += String.fromCharCode(str.charCodeAt(i) + 1);
}
}
return result;
}
Related
I am build an autocomplete that searches off of a CouchDB View.
I need to be able to take the final character of the input string, and replace the last character with the next letter of the english alphabet. (No need for i18n here)
For Example:
Input String = "b"
startkey = "b"
endkey = "c"
OR
Input String = "foo"
startkey = "foo"
endkey = "fop"
(in case you're wondering, I'm making sure to include the option inclusive_end=false so that this extra character doesn't taint my resultset)
The Question
Is there a function natively in Javascript that can just get the next letter of the alphabet?
Or will I just need to suck it up and do my own fancy function with a base string like "abc...xyz" and indexOf()?
my_string.substring(0, my_string.length - 1)
+ String.fromCharCode(my_string.charCodeAt(my_string.length - 1) + 1)
// This will return A for Z and a for z.
function nextLetter(s){
return s.replace(/([a-zA-Z])[^a-zA-Z]*$/, function(a){
var c= a.charCodeAt(0);
switch(c){
case 90: return 'A';
case 122: return 'a';
default: return String.fromCharCode(++c);
}
});
}
A more comprehensive solution, which gets the next letter according to how MS Excel numbers it's columns... A B C ... Y Z AA AB ... AZ BA ... ZZ AAA
This works with small letters, but you can easily extend it for caps too.
getNextKey = function(key) {
if (key === 'Z' || key === 'z') {
return String.fromCharCode(key.charCodeAt() - 25) + String.fromCharCode(key.charCodeAt() - 25); // AA or aa
} else {
var lastChar = key.slice(-1);
var sub = key.slice(0, -1);
if (lastChar === 'Z' || lastChar === 'z') {
// If a string of length > 1 ends in Z/z,
// increment the string (excluding the last Z/z) recursively,
// and append A/a (depending on casing) to it
return getNextKey(sub) + String.fromCharCode(lastChar.charCodeAt() - 25);
} else {
// (take till last char) append with (increment last char)
return sub + String.fromCharCode(lastChar.charCodeAt() + 1);
}
}
return key;
};
Here is a function that does the same thing (except for upper case only, but that's easy to change) but uses slice only once and is iterative rather than recursive. In a quick benchmark, it's about 4 times faster (which is only relevant if you make really heavy use of it!).
function nextString(str) {
if (! str)
return 'A' // return 'A' if str is empty or null
let tail = ''
let i = str.length -1
let char = str[i]
// find the index of the first character from the right that is not a 'Z'
while (char === 'Z' && i > 0) {
i--
char = str[i]
tail = 'A' + tail // tail contains a string of 'A'
}
if (char === 'Z') // the string was made only of 'Z'
return 'AA' + tail
// increment the character that was not a 'Z'
return str.slice(0, i) + String.fromCharCode(char.charCodeAt(0) + 1) + tail
}
Just to explain the main part of the code that Bipul Yadav wrote (can't comment yet due to lack of reps). Without considering the loop, and just taking the char "a" as an example:
"a".charCodeAt(0) = 97...hence "a".charCodeAt(0) + 1 = 98 and String.fromCharCode(98) = "b"...so the following function for any letter will return the next letter in the alphabet:
function nextLetterInAlphabet(letter) {
if (letter == "z") {
return "a";
} else if (letter == "Z") {
return "A";
} else {
return String.fromCharCode(letter.charCodeAt(0) + 1);
}
}
var input = "Hello";
var result = ""
for(var i=0;i<input.length;i++)
{
var curr = String.fromCharCode(input.charCodeAt(i)+1);
result = result +curr;
}
console.log(result);
I understand the original question was about moving the last letter of the string forward to the next letter. But I came to this question more interested personally in changing all the letters in the string, then being able to undo that. So I took the code written by Bipul Yadav and I added some more code. The below code takes a series of letters, increments each of them to the next letter maintaining case (and enables Zz to become Aa), then rolls them back to the previous letter (and allows Aa to go back to Zz).
var inputValue = "AaZzHello";
console.log( "starting value=[" + inputValue + "]" );
var resultFromIncrementing = ""
for( var i = 0; i < inputValue.length; i++ ) {
var curr = String.fromCharCode( inputValue.charCodeAt(i) + 1 );
if( curr == "[" ) curr = "A";
if( curr == "{" ) curr = "a";
resultFromIncrementing = resultFromIncrementing + curr;
}
console.log( "resultFromIncrementing=[" + resultFromIncrementing + "]" );
inputValue = resultFromIncrementing;
var resultFromDecrementing = "";
for( var i2 = 0; i2 < inputValue.length; i2++ ) {
var curr2 = String.fromCharCode( inputValue.charCodeAt(i2) - 1 );
if( curr2 == "#" ) curr2 = "Z";
if( curr2 == "`" ) curr2 = "z";
resultFromDecrementing = resultFromDecrementing + curr2;
}
console.log( "resultFromDecrementing=[" + resultFromDecrementing + "]" );
The output of this is:
starting value=[AaZzHello]
resultFromIncrementing=[BbAaIfmmp]
resultFromDecrementing=[AaZzHello]
if i have "google chrome great" the output vowel is "oooeeea" and consonant is "ggglchrrt".
i try this code, but the output is "test.js:26 ooeoeea"
test("google crhome great")
function test(e){
var words = e.split("");
var vowels = "AIUEOaiueo";
var vowel = "";
for(var i = 0; i < e.length; i++){
if(vowels.includes(e[i])){
if(e[i] == 'a' || e[i] == 'A'){
vowel += e[i];
}
if(e[i] == 'i' || e[i] == 'I'){
vowel += e[i];
}
if(e[i] == 'u' || e[i] == 'U'){
vowel += e[i];
}
if(e[i] == 'e' || e[i] == 'E'){
vowel += e[i];
}
if(e[i] == 'o' || e[i] == 'O'){
vowel += e[i];
}
}
}
console.log(vowel);
}
To order the values properly, consider putting them onto an object instead, indexed by letter. On each iteration, concatenate onto (or create) the property. At the end, take the object's values.
test("google crhome great")
function test(e){
const letters = {};
for (const letter of e) {
if (/[aeiou]/i.test(letter)) {
letters[letter] = (letters[letter] || '') + letter;
}
}
const vowels = Object.values(letters).join('');
console.log(vowels);
}
This works because it'll iterate over the string to construct an object like
{
o: 'ooo',
e: 'eee',
a: 'a',
}
and then you just need to join the values together to get your string.
Use a character set in a regular expression to keep the vowel test concise.
If you need consonants too:
test("google crhome great")
function test(e){
const vs = {};
const cs = {};
for (const letter of e.replaceAll(' ', '')) {
const obj = /[aeiou]/i.test(letter) ? vs : cs;
obj[letter] = (obj[letter] || '') + letter;
}
const vowels = Object.values(vs).join('');
const consonants = Object.values(cs).join('');
console.log(vowels, consonants);
}
you can do sth like
console.log(test("google crhome great"))
function test(e){
var words = e
.toLowerCase() // for better compare and sort
.split("") // convert string to array
.filter(el => el !== " ") // remove spaces
var vowel = words
.filter(el => "aiueo" // to find vowel letters
.split("") // to create vowel letter array
.includes(el)
).sort((a,b) =>
a.localeCompare(b) // sort from a to z. you can replace a with b and b with a for reverse sorting
).join('') // to convert array to string
var consonant = words
.filter(el => !"aiueo"
.split("")
.includes(el)
).sort((a,b) =>
a.localeCompare(b)
).join('')
return {vowel, consonant}
}
I'm trying to solve the problem of: Given an array of strings with only lower case letters, make a function that returns an array of those same strings, but each string has its letters rearranged such that it becomes a palindrome (if not possible then return -1). I'm a bit stuck on how I should be rearranging the letters.
let arr = ["hello", "racecra"];
I created a function to first check if a word is a palindrome :
function isPalindrome(arr) {
let obj = {};
for (var x = 0; x < str.length; x++) {
if (obj[arr[x]]) {
obj[arr[x]] += 1;
} else {
obj[arr[x]] = 1;
}
}
let countOdd = 0;
let countEven = 0;
for (let x of Object.values(obj)) {
if (x % 2 == 0) {
countEven += 1;
} else {
countOdd += 1;
}
}
return countOdd == 1 ? true : false
}
then I plan to loop through the words
let emptyArr = [];
for (var x = 0; x < arr.length; x++) {
if (isPalindrome(arr[x]) {
// not sure what to do here. I know the word is a palindrome but not sure how to sort the order of the word in the palindrome form.
} else {
emptyArr.push(-1);
}
}
return emptyArr;
Look closely: you don't need your words to be palindromes, you need them to be rearrangeable as palindromes ("palindrome-candidates"). Now, a word is a palindrome-candidate if all of its letters but one can be counted by an even number (2, 4, 6 etc.)
For example, this...
hollo
... is NOT a palindrome, but can become one, as there's 2 'o', 2 'l' and just one 'h' in it. To rearrange, you just move 'h' in the middle, then just place 'o' and 'l' before and after it:
l -> o -> h <- o <- l
So start with splitting each of your words by characters, then either count those characters or just sort them (as #Barmar suggested). If they satisfy the condition, rearrange the letters following the approach given; if not, return null (or any other special value clearly distinguishable from the rest) immediately.
Here's one way to do it:
function rearrangeAsPalindrome(word) {
if (word.length === 1) return word; // easy win first
const charCounter = word.split('').reduce((counter, ch) => ({
...counter,
[ch]: (counter[ch] || 0) + 1
}), {});
const parts = ['', '', '']; // left, middle, right
const entries = Object.entries(charCounter);
for (let i = 0; i < entries.length; ++i) {
const [char, counter] = entries[i];
if (counter % 2) { // odd
if (parts[1] !== '') return null;
// one odd is already here, eject! eject!
parts[1] = char.repeat(counter);
}
else { // even
const half = counter / 2;
parts[0] = char.repeat(half) + parts[0];
parts[2] += char.repeat(half);
}
}
return parts.join('');
}
console.log(rearrangeAsPalindrome('racarrrac')); // crraaarrc
console.log(rearrangeAsPalindrome('aabbcc')); // cbaabc
console.log(rearrangeAsPalindrome('hollo')); // lohol
console.log(rearrangeAsPalindrome('hello')); // null
This function returns null (and does it early) when it realizes the word given cannot be rearranged as a palindrome - or an actual palindrome if it is possible.
This can help
"How to generate distinct palindromes from a string in JavaScript"
https://medium.com/#bibinjaimon/how-to-generate-distinct-palindromes-from-a-string-in-javascript-6763940f5138
I am trying to replace all the letters of a string by the next letter in the alphabet.
For example: a --> b or i --> j.
My program is ignoring the if statement that checks a letter against the alphabet array. When I try running the code it replaces all letters by "A", the last element in the alphabet array.
Although inefficent, I cannot find any errors with this algorithm. So why is the program ignoring the if statement?
function LetterChanges(str){
var alphabet = ["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","a"];
str = str.toLowerCase();
var ans = str.split("");
for(i = 0; i < ans.length; i ++)//Running through for each letter of the input string
{
for(a = 0; a < 26; a++)//Checking each letter against the alphabet array
{
if(alphabet[a] == ans[i])
{
ans[i] = alphabet[a+1];
}
}
}
return ans;
}
LetterChanges("Argument goes here");
The reason why it is not working, is because the ans array is modified, whilst you are still checking it.
In this loop:
for(a = 0; a < 26; a++)//Checking each letter against the alphabet array
{
if(alphabet[a] == ans[i])
{
ans[i] = alphabet[a+1];
}
}
If the if statement is found to be true, ans[i] will be updated, but then on the next loop of the iteration, it will likely be true again, as you are checking against the updated ans[i] variable.
As #xianshenglu suggested, you can fix this issue by adding a break to escape from the inner loop once a correct match is found.
for(a = 0; a < 26; a++) {
if(alphabet[a] == ans[i]) {
ans[i] = alphabet[a+1]
// escape from the inner loop once a match has been found
break
}
}
For an alternative way to do this, you could do the following:
var result = str.toLowerCase().split('').map(ch => {
var pos = alphabet.indexOf(ch)
return pos >= 0 ? alphabet[pos + 1] : ch
}).join('')
And if you want to get rid of the alphabet array, you can use char codes. For example:
var result = str.toLowerCase().split('').map(ch => {
var code = ch.charCodeAt(0)
if(code < 96 || code > 122){ return ch }
return String.fromCharCode((code - 96) % 26 + 97)
}).join('')
you lost break when if executed
function LetterChanges(str){
var alphabet = ["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","a"];
str = str.toLowerCase();
var ans = str.split("");
for(i = 0; i < ans.length; i ++)//Running through for each letter of the input string
{
for(a = 0; a < 26; a++)//Checking each letter against the alphabet array
{
if(alphabet[a] == ans[i])
{
ans[i] = alphabet[a+1];
break;
}
}
}
return ans;
}
console.log(LetterChanges("Argument goes here"));
I have a variable which contains this:
var a = "hotelRoomNumber";
Is there a way I can create a new variable from this that contains: "Hotel Room Number" ? I need to do a split on the uppercase character but I've not seen this done anywhere before.
Well, you could use a regex, but it's simpler just to build a new string:
var a = "hotelRoomNumber";
var b = '';
if (a.length > 0) {
b += a[0].toUpperCase();
for (var i = 1; i != a.length; ++i) {
b += a[i] === a[i].toUpperCase() ? ' ' + a[i] : a[i];
}
}
// Now b === "Hotel Room Number"
var str = "mySampleString";
str = str.replace(/([A-Z])/g, ' $1').replace(/^./, function(str){ return str.toUpperCase(); });
http://jsfiddle.net/PrashantJ/zX8RL/1/
I have made a function here:
http://jsfiddle.net/wZf6Z/2/
function camelToSpaceSeperated(string)
{
var char, i, spaceSeperated = '';
// iterate through each char
for (i = 0; i < string.length; i++) {
char = string.charAt(i); // current char
if (i > 0 && char === char.toUpperCase()) { // if is uppercase
spaceSeperated += ' ' + char;
} else {
spaceSeperated += char;
}
}
// Make the first char uppercase
spaceSeperated = spaceSeperated.charAt(0).toUpperCase() + spaceSeperated.substr(1);
return spaceSeperated;
}
The general idea is to iterate through each char in the string, check if the current char is already uppercased, if so then prepend a space to it.