JS toLowerCase() not working - javascript

I have this code :
//make first letter of each word capital
function titleCase(str) {
/*
* 1. change all letters to lower case
* 2. split words
* 3. set each 1st letter to Capital
* 4. combine array back into string
*/
arr = [];
str.toLowerCase();
arr = str.split(" ");
for (var index = 0; index < arr.length; index++) {
arr[index].charAt(0).toUpperCase();
}
str= arr.join(" ");
return str;
}
console.log(titleCase("Potato potato potato"));
And I don't understand why toLowerCase() and toUpperCase() are not working. What am I doing wrong ?

There are 2 updates required
Reassign str.toLowerCase() to str
Reassign updated array value back in array.
Please note, until and unless you reassign the values, the original value does not change. Hence, the result remained unaffected.
//make first letter of each word capital
function titleCase(str) {
/*
1. change all letters to lower case
2. split words
3. set each 1st letter to Capital
4. combine array back into string
*/
arr = [];
str = str.toLowerCase(); // **** Problem 1 - Reassigning
arr = str.split(" ");
for (var index = 0; index < arr.length; index++) {
// **** Problem 2 - Reassigning
arr[index] = arr[index].charAt(0).toUpperCase() + arr[index].slice(1);
}
str= arr.join(" ");
return str;
}
console.log(titleCase("Potato potato potato"));

You need to reassign (overwrite) the value inside the array after you change it. Otherwise, the array remains unchanged. Besides, you forgot to add the rest of the string (arr[index].slice(1)) to the uppercased letter.
function titleCase(str) {
let arr = [];
str.toLowerCase();
arr = str.split(" ");
for (var index = 0; index < arr.length; index++) {
arr[index] = arr[index].charAt(0).toUpperCase() + arr[index].slice(1); // <-- Changes
}
str= arr.join(" ");
return str;
}
console.log(titleCase("Potato potato potato"));
EDIT
Here is my own ES6 one-liner version :
titleCase = str => str.trim().split(" ").map( word => word.charAt(0).toUpperCase() + word.slice(1) ).join(" ")
console.log(titleCase("Potato potato potato"));
Explanation :
titleCase = str => str
.trim() // Removes extra spaces
.split(" ")
.map( word =>
word.charAt(0).toUpperCase() + word.slice(1) // Uppercases 1st letter, adds the rest of the word, returns the whole
)
.join(" ") // Reforms a string

you can simply do
function convert(str){
return str.split(' ').map(e => e.replace(/([A-Za-z])(\w+)/, (x, y, z) => y.toUpperCase()+z.toLowerCase())).join(' ');
}
console.log(convert('Potato potato pOtato'))

short solution:
var titleCase = (str)=>str.toLowerCase().split(' ').map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(' ');
calling:
titleCase('Potato potato potato');
Splitting the string by space and map a lambda to the resulting array. The lambda turns up the first letter and append the rest of the word.
as pointed out in the comments:
var titleCase = (str)=>str.toLowerCase().split(' ').reduce((currentString, word)=>currentString+(currentString ? ' ':'')+word.charAt(0).toUpperCase()+word.slice(1));
this works also and loops only one time.

Related

Javascript - Removing last 3 words from a string

I've been able to find examples of how to remove the last word of a string, but in this instance I'm attempting to remove the last 3 words of a string. I've attempted this by adjusting some of the answers I've come across to remove a single word but none have gave me the expected results.
Example string Highest ranked in the states
I would like my return value be Highest ranked
Here are some code snippets of what I've attempted:
let myString = "Highest ranked in the states";
myString = myString.substring(2, myString.lastIndexOf(" "));
console.log(myString)
let myString2 = "I want to remove the last word";
let mySplitResult2 = myString2.split(" ");
let lastWord = mySplitResult2[mySplitResult2.length-3]
console.log(lastWord)
with the adjusting the substring method to (2, myString.lastIndexOf(" ")); it ended up removing the first two letters of my sentence and only removed the word states such as "guest ranked in the"
when adjusting the .split() method to length -3 it simply returns back the word in instead of in the states
Here is a nice and readable one liner:
const remove3words = words => words.split(" ").slice(0, -3).join(" ");
console.log(remove3words("Highest ranked in the states"));
console.log(remove3words("Exactly three words"));
You can generalize it easily to n words in the following way:
function remove_n_words(words, n) {
return n === 0 ? words : words.split(" ").slice(0, -n).join(" ");
}
// Test the function
console.log(remove_n_words("Highest ranked in the states", 0));
console.log(remove_n_words("Highest ranked in the states", 3));
console.log(remove_n_words("Highest ranked in the states", 100));
let myString = "Highest ranked in the states";
myString = myString.split(' ')
myString = myString.splice(myString.length-5,2)
myString = myString.join(' ')
console.log(myString)
See comments for explanation using split and splice
let myString = "Highest ranked in the states";
//split the str using blank space between each word and add to new variable
let str = myString.split(" ");
//get the length
let num = str.length;
//splice the array removing the last three values with the number - 3
let newStr = str.splice(0, num - 3);
let displayText = '';
//back into string
newStr.forEach(function(value){
displayText += value + ' ';
});
display.textContent = displayText;
<div id="display"></div>
Here's a function that can do that for you. (It can actually remove all characters from the Nth-to-last occurrence of any character you specify, not just the Nth-to-last word.)
In your case:
the char parameter should get the value ' ' (ie spaces between words)
N should get the value 3 (to target the 3rd-to-last space)
I added an excludeChar parameter that you can set to true to avoid returning the final space (or you can use the .trim method on the result).
const
myString = "Highest ranked in the states",
result = truncateAtNthToLastOccurencOfChar(myString, ' ', 3);
console.log(result);
function truncateAtNthToLastOccurencOfChar(str, char, N, excludeChar){
// Makes counter, converts str to arr & reverses it
let i = -1, rev = Array.from(str).reverse();
// Increments counter (and executes even when i=0)
while(++i || true){
// Returns original string if at the end `char` has occured fewer than `N` times
if(i >= rev.length - 1){
return str;
}
// If current character matches `char`, decrements `N`
if(rev[i] == char && --N === 0){
// If N=0, `i` is our target, all keeps characters (from reversed array)
// starting at `i` (or after `i` if excludeChar=true)
return rev
// The occurence of char can be excluded from result
.slice(excludeChar ? (i + 1) : i)
.reverse() // Restores original character order
.join(''); // Converts back to string
}
}
}

Insert Spaces into string at an index

I'm trying to do this Codewars problem.
Task
In this simple Kata your task is to create a function that turns a string into a Mexican Wave. You will be passed a string and you must return that string in an array where an uppercase letter is a person standing up.
Rules
The input string will always be lower case but maybe empty.
If the character in the string is whitespace then pass over it as if it was an empty seat.
Example
wave("hello") => ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
My code so far is hosted on this repl.it
My thought process is as follows:
Turn argument into array
manipulate each index of the array at index and then readjust previous index to make a wave pattern
turn array into string
reinsert spaces before logging it to console and restarting the loop
I'm pretty stuck and my mind is stuck on how to use
for(var j = 0; j < indexSpaceNumber.length; j++){
//join and add in the spaces at their former index before returning string
strToArray[indexSpaceNumber[j]].slice(0, " ");
}
to insert the spaces into the string.
If there's any guidance or tips it would be much appreciated. I feel like I'm close, but so frustratingly far.
The main idea would be:
Iterate the characters
Replace the character in the original string with an uppercase version
You can use Array.from() to convert the string to an array, and map each item to a new string. If the character is a space return something falsy (en empty string in the example). After the creating the array, filter all falsy values:
const wave = str =>
Array.from(str, (c,i) => // convert the string to an array
// replace the character with an uppercase version in the original string
c === ' ' ?
''
:
`${str.substring(0, i)}${c.toUpperCase()}${str.substring(i + 1)}`
).filter(c => c)
const result = wave("hello")
console.log(result)
For string with spaces
function wave(str) {
let res = []
str.toLowerCase().split('').forEach((v, i) => {
if(v == ' ') return;
res.push( str.substr(0, i) + v.toUpperCase() + str.substr(i + 1) )
});
return res
}
console.log(wave("hello hello"))
I'd go recursive ;)
You know that for a string of length n you need an array of the same length. That's your exit condition.
You can use the length of the array at each iteration to work out the shape of the next string:
hello [] [Hello] 0: uppercase 1st char and append
hello [Hello] [Hello hEllo] 1: uppercase 2nd char and append
hello [Hello hEllo] [Hello hEllo heLlo] 2: uppercase 3rd char and append
...
const wave =
(str, arr = []) =>
str.length === arr.length
? arr
: wave
( str
, [ ...arr
, str.slice(0, arr.length)
+ str[arr.length].toUpperCase()
+ str.slice(arr.length + 1)
]
);
console.log(wave('hello'));
Go over each char in string and build
Slice str from start till current char + current char to upper case + Slice str from current char to end
const wave = str => {
const res = [];
for (let i = 0; i < str.length; i++) {
res.push(`${str.slice(0, i)}${str[i].toUpperCase()}${str.slice(i + 1)}}`);
}
return res;
};
console.log(wave("hi my name is rylan"));
// Alternate way to do with Array.splice
const wave2 = str => {
const res = [];
for (let i in str) {
const temp = Array.from(str);
temp.splice(i, 1, temp[i].toUpperCase());
res.push(temp)
}
return res.map(x => x.join(''));
};
console.log(wave2("hi my name is rylan"));

How to reverse word by word in a string using javascript?

I'm writing the logic for reverse word by word in string javascript.
But I'm thinking my code is more lengthy so, I'm looking for good answer.
Ex :- I/p- Hi how are you // o/p- iH woh era uoy
function ReverseString(val) {
var op = "",
iCount = -1;
for (let i = 0; i <= val.length; i++) {
if (val[i] != " " && i != val.length)
continue;
for (let j = i - 1; j > iCount; j--)
op += val[j];
if (i != val.length)
op += " ";
iCount = i;
}
return op;
}
console.log(ReverseString("Hi how are you"));
One way would be to split the string by whitespace to have an array of words, then reverse those words within the array using map(), like this:
function ReverseString(val) {
return val.split(/\s/g).map(w => w.split('').reverse().join('')).join(' ');
}
console.log(ReverseString("Hi how are you"));
Your solution.
<script>
rev=(val)=>{
return val.split("").reverse().join("").split(" ").reverse().join(" ")
}
console.log(rev('Hi how are you'))
</script>
A way to do this is to seperate you words in an array using split()
Then for each word, split the letters and use the reverse function and re-join them.
At least, re-join the word
const str = "Hi how are you";
let str_reversed = str.split(' ');// put each word in an array
str_reversed = str_reversed.map(word => word.split('').reverse().join('')); // for each word, we put each letter in array, reverse them and then re-join them
str_reversed = str_reversed.join(' '); // rejoin the word
console.log(str_reversed);
A one line solution to reverse each word maintaining the order:
var original = 'Hi how are you';
var reversed = original.split("").reverse().join("").split(" ").reverse().join(" ")
o/p: "iH woh era uoy"
let str = 'Hi how are you';
let reverse = str
.split("")
.reverse()
.join("")
.split(" ")
.reverse()
.join(" ")
);

Can't capitalize the first letter of the word

I am trying to capitalize the first letter of every word in the string. I wanted to do it in 3 steps:
Turn string into an array using .split().
Create a loop and change the first letter in every word by addressing it with an array index.
Finally I wanted to use .join to put everything back in a string.
But something went wrong and I can't go to the 3rd step. The for loop does change the letter to uppercase, but when I return the variable cap it only returns the first capitalized letter of the last word in the string. In the example it's P(the last word is pot), if I erase pot it returns T(because tea becomes the last word).
Why doesn't the cap variable return the whole array with capitalized first letters? What am I missing?
Here's the code:
function titleCase(str) {
var arr = str.split(" ");
for (i = 0; i < arr.length; i++) {
var cap = arr[i][0].toUpperCase();
}
return cap;
}
titleCase("I'm a little tea pot");
That's because you're just returning the cap variable which will contain the last words first letter to upper case (left by last iteration).
function titleCase(str) {
var arr = str.split(" ");
for (i = 0; i < arr.length; i++) {
var word = arr[i];
// capitalized first letter + rest of the word
var capitalizedWord = word[0].toUpperCase() + word.slice(1);
arr[i] = capitalizedWord; // replace the uncapitalized word with capitalized one
}
return arr.join(" "); // join with spaces to make it a sentence again
}
titleCase("I'm a little tea pot");
It's because cap is only a variable so as you loop through your words it keeps getting overwritten by the first letter of the next word. Make it an array or concatenate the next letter onto it.
I think this is the answer:
const capitalizeFirst = data => data.replace(/[\w']+/g, x => x[0].toUpperCase() + x.slice(1).toLowerCase())
console.log(capitalizeFirst("I'm a little tea pot"))
You are overriding the variable cap in each iteration.
Your code slightly modified:
function titleCase(str) {
var arr = str.split(" ");
var cap = "";
for (i = 0; i < arr.length; i++) {
if (i != arr.length - 1) {
cap += arr[i][0].toUpperCase() + arr[i].substr(1) + " ";
} else {
cap += arr[i][0].toUpperCase() + arr[i].substr(1);
}
}
return cap;
}
titleCase("I'm a little tea pot");
You are committing a cardinal sin of Javascript! Don't ever declare variables inside of a loop.
function titleCase(str) {
var cap;
var arr = str.split(" ");
for (i = 0; i < arr.length; i++) {
cap = arr[i][0].toUpperCase();
}
return cap;
}
Would be the proper way to type what you have written.
When your for loop iterates in your example, it re-declares the variable each time which causes some bad things to happen. In my example, it is re-defined each time but only declared once.
However, this is all still incorrect for your problem. This will only give you the single letter when you want the entire string. Try something like this
function titleCase(str) {
var arr = str.split(" ");
var wordToCap;
var capWord;
var capArray = [];
for (var i = 0; i < arr.length; i++) {
wordToCap = arr[i];
capWord = wordToCap.charAt(0).toUpperCase() + wordToCap.substring(1);
capArray.push(capWord);
}
return capArray.join(" ");
}
There are much more elegant ways of solving this problem, but hopefully all the steps broken down here will help you understand what your loop is doing and should be doing.
Good luck!
ES2015 solution:
const titleCase = str =>
str.split(' ').map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' ');
titleCase("I'm a little tea pot"));
Working example: https://jsfiddle.net/ecdkxrjd/

Based on user's choice for CharAt, how can I add the rest of the sentence?

I have this simple function, where user can type a sentence and it will capitalze one letter, based on user's choice. For example if user choose to capitalize first letter for sentence "hey" he would write titleCase("hey", 0) but it will only return that one capitalized letter instead of the whole "Hey" word. It's because I have splited it into array, but how can I return the whole word, not only the capitalized one? My code
function titleCase(str, userChoice) {
var string = str;
var split = string.split(" ");
for (i = 0; i < split.length; i++) {
split[i] = split[i].charAt(userChoice).toUpperCase(); + split[i].slice(0);
}
console.log (split.join(" "));
}
titleCase();
How about this?
Just capitalize the index user selected and then return the string.
function titleCase(str, userChoice) {
var string = str;
var split = string.split("");
split[userChoice] = split[userChoice].toUpperCase();
return (split.join(''));
}
console.log(titleCase('hey', 0))
Issue I noticed in your code:
string.split(" "); -> this will split the string at space but your string is one word so it is never split.
function titleCase(str, userChoice) {
var str = str;
var split = str.split(" ");
split[userChoice] = capitalize(split[userChoice]);
return split.join(" ");
}
function capitalize(s) {
return s[0].toUpperCase() + s.substr(1, s.length - 1)
}
console.log(titleCase('hello world', 0));
console.log(titleCase('hello world', 1));

Categories

Resources