var name = "AlbERt EINstEiN";
function nameChanger(oldName) {
var finalName = oldName;
// Your code goes here!
finalName = oldName.toLowerCase();
finalName = finalName.replace(finalName.charAt(0), finalName.charAt(0).toUpperCase());
for(i = 0; i < finalName.length; i++) {
if (finalName.charAt(i) === " ")
finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
}
// Don't delete this line!
return finalName;
};
// Did your code work? The line below will tell you!
console.log(nameChanger(name));
My code as is, returns 'Albert einstein'. I'm wondering where I've gone wrong?
If I add in
console.log(finalName.charAt(i+1));
AFTER the if statement, and comment out the rest, it prints 'e', so it recognizes charAt(i+1) like it should... I just cannot get it to capitalize that first letter of the 2nd word.
There are two problems with your code sample. I'll go through them one-by-one.
Strings are immutable
This doesn't work the way you think it does:
finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
You need to change it to:
finalName = finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
In JavaScript, strings are immutable. This means that once a string is created, it can't be changed. That might sound strange since in your code, it seems like you are changing the string finalName throughout the loop with methods like replace().
But in reality, you aren't actually changing it! The replace() function takes an input string, does the replacement, and produces a new output string, since it isn't actually allowed to change the input string (immutability). So, tl;dr, if you don't capture the output of replace() by assigning it to a variable, the replaced string is lost.
Incidentally, it's okay to assign it back to the original variable name, which is why you can do finalName = finalName.replace(...).
Replace is greedy
The other problem you'll run into is when you use replace(), you'll be replacing all of the matching characters in the string, not just the ones at the position you are examining. This is because replace() is greedy - if you tell it to replace 'e' with 'E', it'll replace all of them!
What you need to do, essentially, is:
Find a space character (you've already done this)
Grab all of the string up to and including the space; this "side" of the string is good.
Convert the very next letter to uppercase, but only that letter.
Grab the rest of the string, past the letter you converted.
Put all three pieces together (beginning of string, capitalized letter, end of string).
The slice() method will do what you want:
if (finalName.charAt(i) === " ") {
// Get ONLY the letter after the space
var startLetter = finalName.slice(i+1, i+2);
// Concatenate the string up to the letter + the letter uppercased + the rest of the string
finalName = finalName.slice(0, i+1) + startLetter.toUpperCase() + finalName.slice(i+2);
}
Another option is regular expression (regex), which the other answers mentioned. This is probably a better option, since it's a lot cleaner. But, if you're learning programming for the first time, it's easier to understand this manual string work by writing the raw loops. Later you can mess with the efficient way to do it.
Working jsfiddle: http://jsfiddle.net/9dLw1Lfx/
Further reading:
Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?
slice() method
You can simplify this down a lot if you pass a RegExp /pattern/flags and a function into str.replace instead of using substrings
function nameChanger(oldName) {
var lowerCase = oldName.toLowerCase(),
titleCase = lowerCase.replace(/\b./g, function ($0) {return $0.toUpperCase()});
return titleCase;
};
In this example I've applied the change to any character . after a word boundary \b, but you may want the more specific /(^| )./g
Another good answer to this question is to use RegEx to do this for you.
var re = /(\b[a-z](?!\s))/g;
var s = "fort collins, croton-on-hudson, harper's ferry, coeur d'alene, o'fallon";
s = s.replace(re, function(x){return x.toUpperCase();});
console.log(s); // "Fort Collins, Croton-On-Hudson, Harper's Ferry, Coeur D'Alene, O'Fallon"
The regular expression being used may need to be changed up slightly, but this should give you an idea of what you can do with regular expressions
Capitalize Letters with JavaScript
The problem is twofold:
1) You need to return a value for finalName.replace, as the method returns an element but doesn't alter the one on which it's predicated.
2) You're not iterating through the string values, so you're only changing the first word. Don't you want to change every word so it's in lower case capitalized?
This code would serve you better:
var name = "AlbERt EINstEiN";
function nameChanger(oldName) {
// Your code goes here!
var finalName = [];
oldName.toLowerCase().split(" ").forEach(function(word) {
newWord = word.replace(word.charAt(0), word.charAt(0).toUpperCase());
finalName.push(newWord);
});
// Don't delete this line!
return finalName.join(" ");
};
// Did your code work? The line below will tell you!
console.log(nameChanger(name));
if (finalName.charAt(i) === " ")
Shouldn't it be
if (finalName.charAt(i) == " ")
Doesn't === check if the object types are equal which should not be since one it a char and the other a string.
Related
I am trying to use replace with a while loop. I want to replace the first letter in the string with an empty string if the letters is not a vowel. The regex I have used is working because the letters are added to the end of the string, just not sure what is happening with the replace function?
Here is my code:
vowel = new RegExp("[aeiou]");
word = "cherry";
var moved = '',
i = 0;
while (!vowel.test(word[i])) {
moved += word[i];
word.replace(word[i], '');
i++;
}
return word+moved;
For example, 'cherrych' will be returned rather than 'errych'
You don't need a loop here, just use standard regex multiple selectors, e.g. see the following:
'cherrych'.replace(/^[^aeiou]*/, '')
String.prototype.replace returns a modified copy of the string, and does not alter the string in place.
Every time you do word.replace(), you cause a new string to be returned but importantly word is not altered at all.
The right way to attack this is then to assign this new modified copy to the original by
word = word.replace(word[i],'');
var a="how are you?";
In the above example I want to store the second word "are" into another variable in a single step.
I don't want to use something like below
var bigArray = a.split(" ");
var secondText = bigArray[1];
as we may need to store the entire paragraph into a big array and consume a lot of memory without any use.
I would like to know if there is some function which works as below
var secondText=specialFunction(a," ",1);
so that we will get the second substring when the paragraph is split by " "
Well, I would spend my time worrying about more important things than the size of some arrays.
Anyway, you could try using a regexp:
var secondText = (a.match(/ (\w+)/) || []) [1];
This reads as "find a space, then capture the following word".
The || [] part is meant to deal with the situation where there is no match (for example, no second word). In that case, the result will be [][1] which is undefined.
This finds only the second word. What about the more general case? Since we are not allowed to split the string on spaces, because that would create an array and the OP doesn't want that due to memory concerns. So, we will instead build a dynamic regexp. To find the nth word, we want to skip over the first n-1 spaces. Or, to be more precise, we want to skip over the first word, some spaces, then the second word, then some more spaces, etc. So the regexp is
/(?:\w+ ){n}(\w+)/
^^ NO CAPTURING GROUP
^^^^ WORD FOLLOWED BY SPACE
^^^ N TIMES
^^^^^ CAPTURE FOLLOWING WORD
The ?: is to avoid this being treated as a capturing group. We build the regexp using
function make_nth_word_regexp(n) {
n--;
return new RegExp("(?:\\w+ ){" + n + "}(\\w+)");
}
Now look for your nth word:
var fifth_word = str.match(make_nth_word_regexp(5)) [1];
> "Hey there you".match(make_nth_word_regexp(3))[1]
< "you"
Alternative to regex is just to use substring(). Something like
var a="how are you";
alert(a.substring(a.indexOf(" "), a.length).substring(0, a.indexOf(" ")+1));
There is a part in my string from, to which I would like to replace to an another string replace_string. My code should work, but what if there is an another part like the returned substring?
var from=10, to=17;
//...
str = str.replace(str.substring(from, to), replace_string);
For example:
from=4,to=6
str = "abceabxy"
replace_string = "zz"
the str should be "abcezzxy"
What you want to do is simple! Cut out and replace the string. Here is the basic tool, you need scissor and glue! Oops I mean string.Split() and string.Replace().
How to use?
Well I am not sure if you want to use string.Split() but you have used string.Replace() so here goes.
String.Replace uses two parameters, like this ("one", "two") what you need to make sure is that you are not replacing a char with a string or a string with a char. They are used as:
var str="Visit Microsoft!";
var n=str.replace("Microsoft","W3Schools");
Your code:
var from=10, to=17;
//...
var stringGot = str.replace(str.substring(from, to), replace_string);
What you should do will be to split the code first, and then replace the second a letter! As you want one in your example. Thats one way!
First, split the string! And then replaced the second a letter with z.
For String.Replace refer this: http://www.w3schools.com/jsref/jsref_replace.asp
For String.SubString: http://www.w3schools.com/jsref/jsref_substring.asp
For String.Split: http://www.w3schools.com/jsref/jsref_split.asp
Strings are immutable. This means they do not change after they are first instantiated. Every method to manipulate a string actually returns a new instance of a string. So you have to assign your result back to the variable like this:
str = str.replace(str.substring(from, to), replace_string);
Update: However, the more efficient way of doing this in the first place would be the following. it is also less prone to errors:
str = str.substring(0, from) + replace_string + str.substring(to);
See this fiddle: http://jsfiddle.net/cFtKL/
It runs both of the commands through a loop 100,000 times. The first takes about 75ms whereas the latter takes 20ms.
I'm trying to return the first 5 words of a string in a readable format, no "" or commas separating words. I'm not sure if its a regex thing or what, but I can't figure it out although its probably simple. Thanks!
See what I have thus far:
http://jsfiddle.net/ccnokes/GktTd/
This is the function I'm using:
function getWords(string){
var words = string.split(/\s+/).slice(1,5);
return words;
}
The only thing you are missing is a join()
Try this:
function getWords(str) {
return str.split(/\s+/).slice(0,5).join(" ");
}
This will do something like:
var str = "This is a long string with more than 5 words.";
console.log(getWords(str)); // << outputs "This is a long string"
Take a look at this link for a further explanation of the .join(). function in javascript. Essentially - if you don't supply an argument, it uses the default delimiter ,, whereas if you supply one (as I'm doing in the above example, by providing " " - it will use that instead. This is why the output becomes the first 5 words, separated by a space between each.
Those commas are coming from how you output the data:
//write to DOM
$('<h2 />').text(getWords(str).join(' ')).appendTo('body');
When you add a string to getWords(str), javascript tries to convert the array into a string - it does this by joining the words with commas. If you want to join them with something else, use join.
Troy Alford solution is working, but is has one drawback. If between words there will be more than one space, or new line character (\n) it will be converted to single space, e.g:
'jQuery is a
multi-browser'
will be converted to
'jQuery is a multi-browser'
To fix this issue, we might use word boundary regex. It might looks like this:
function getFirstWords(text, wordsAmount) {
const arr = text.split(/\b/g);
const arrItemsAmount = (/\b/.exec(text) && /\b/.exec(text).index) ?
wordsAmount * 2 :
wordsAmount * 2 - 1;
return arr.slice(0, arrItemsAmount).join('');
}
You can do it with str.substring(1,15)
I have a string of text "AB-123-2011-07-09", and need to remove everything except "123", then add a "#" sign to the end result.
The string "123" is ever increasing in number, as is the "2011-07-09" (a date). Only "AB" stays the same.
So the end result would be: #123
Is this possible?
Thanks.
EDIT: Just to clarify, I was needing a script that could globally search a page and replace any text which had the format of "AB-xxx-xxxx-xx-xx" with just the digits highlighted here in bold, then adding the "#" before it.
Currently there are only 3 digits in that position, but in the future there may be four.
My code:
function Replace() {
var OldString = "AB-123-2011-07-09";
var NewString = OldString.replace(/^AB-(\d+)-.*/, "#$1");
document.body.innerHTML = document.body.innerHTML.replace(OldString, NewString);
}
window.onload = Replace();
So far it only replaces 1 instance of the string, and uses a fixed string ("AB-123-2011-07-09").
What regular expression do I need to make the 'OldString' dynamic, rather than it being fixed as it is now?
var data = "AB-123-2011-07-09";
var field = data.split('-')[1];
document.write("#" + field);
http://jsfiddle.net/efortis/8acDr/
The following regex would work, but in this case I don't think you need a regex at all (as #Eric has already shown).
"AB-123-2011-07-09".replace(/^AB-(\d+)-.*/, "#$1");
This results in the value #123
http://jsfiddle.net/3XhbE/
Does this work?
var result = mystring.replace(new RegExp(AB-([0-9]+)-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9], "g"),"#$1");
mystring is the "AB-123-2011-07-09" string and result would be "#123".
This is of course possible. This regex would do the trick:
“AB-123-2011-07-09“.replace(/^AB-(\d+)-\d+-\d+-\d+$/, “#$1“);
It also checks you given syntax and that there is nothing else in the string.
migg