diff --git a/app.js b/app.js
new file mode 100644
index 0000000..1499e46
--- /dev/null
+++ b/app.js
@@ -0,0 +1,369 @@
+document.write("
");
+document.write("
+ You ask the user to enter her city. Then you check her city against a
+ list of the 5 cleanest
+ cities.
+ If the user enters "Cheyenne" or any of the other cleanest cities, your
+ code displays an
+ alert telling her that it's one of the cleanest cities.
+ But what if she enters "cheyenne" instead of "Cheyenne"—as some users
+ inevitably will?
+ When that happens, there will be no match. JavaScript is literal-minded.
+
+ A human knows that in this context "cheyenne" means "Cheyenne." But
+ JavaScript doesn't.
+ We need some way to get JavaScript to recognize the uncapitalized
+ version as a match.
+ One way would be to expand the cleanestCities array to include the
+ uncapitalized
+ versions of all the city names:
+ var cleanestCities = ["Cheyenne", "cheyenne", "Santa Fe", "santa fe",
+ "Tucson", tucson", "Gr eat Falls",
+ "great falls", "Honolulu", "honolulu"];
+ This works up to a point, but it's a lot of extra coding. Plus, if the
+ user enters "santa Fe ,"
+ "Santa fe," or "sAnta Fe," we're back to the original problem. To cover
+ all these possibilit es
+ and others, it would take a mile of code.
+ The solution is to code the array elements in lower-case, and convert
+ the user's input,
+ whatever it is, to lower-case, so we always have apples to compare with
+ apples.
+ 1 var cityToCheck = prompt("Enter your city");
+ 2 cityToCheck = cityToCheck.toLowerCase();
+ 3 var cleanestCities = ["cheyenne", "santa fe", "tucson", "great falls",
+ "honolulu"];
+ 4 for (var i = 0; i <= 4; i++) {
+ 5 if (cityToCheck === cleanestCities[i]) {
+ 6 alert("It's one of the cleanest cities");
+ 7 }
+ 8 }
+ Line 2 is what's new here:
+ 2 cityToCheck = cityToCheck.toLowerCase();
+ The converted string is assigned to a variable. In this case, it's the
+ same variable whose
+ string is being converted, cityToCheck. Note that the keyword
+ toLowerCase must be in
+ camelCase.
+ Note too that the toLowerCase method converts all the characters of the
+ string to lowercase, not just the initial letters. For example,
+ "ChEyEnNe" becomes "cheyenne."
+ You could go the other way and convert everything to upper-case, then
+ test against
+ "CHEYENNE," "SANTA FE, " etc. Most coders prefer the lower-case method.
+ To convert the
+ string to upper-case, you'd write:
+ 2 cityToCheck = cityToCheck.toUpperCase();
+
+ You've asked the user to give you the name of a city. You want to
+ convert the name she's
+ given you to a name with an initial cap. Whether she's input "boston,"
+ "BOSTON", or
+ "bosTon," you want to normalize the input to "Boston." The toLowerCase
+ and toUpperCase
+ methods you learned in the last chapter won't get the job done on their
+ own, because they make
+ the same wholesale change to every character in the string. But if you
+ break the string up into
+ two segments, you can use these methods to get the string into the shape
+ you want. (For now,
+ I'll ignore the possibility that the city name might be made up of two
+ or more words, like New
+ Orleans or Sault Ste. Marie.)
+ To copy a section of a string, you use the slice method. Suppose the
+ user has entered a
+ string, and the string has been assigned to the variable cityToCheck.
+ The following code
+ copies the first character of the string and assigns it to the variable
+ firstChar. The original
+ value of cityToCheck doesn't change. If cityToCheck is "Boston",
+ firstChar is "B".
+ var firstChar = cityToCheck.slice(0, 1);
+ Things to be aware of:
+ A string is indexed like an array. Only, instead of each index number
+ referring to an
+ element, it refers to a character.
+ Like array indexing, string indexing begins with 0.
+ In the slice method, the first number inside the parentheses is the
+ index of the first
+ character in the slice. The second number is not, however, the last
+ character in the slice.
+ It's the first character after the slice. If you subtract the first
+ index from the second index,
+ you'll always get the length of the slice.
+ Here's another example.
+ var someChars = cityToCheck.slice(2, 5);
+ Again let's say that the string is "Boston". The slice begins with the
+ index-2 (the third)
+ character, "s". It ends with the character before the index-5 character,
+ "n". someChars is "sto".
+ If you omit the second number inside the parentheses, JavaScript
+ includes all the
+ characters to the end of the string.
+ var someChars = cityToCheck.slice(2);
+ The slice begins with the index-2 (the third) character, "s". Since no
+ cutoff at the end is
+ specified, the slice ends with the last character of the string.
+ someChars is "ston".
+ Now we have a way to capitalize the first character of a string and
+ insure that the
+ remaining letters are lower-case.
+ 1 var firstChar = cityToCheck.slice(0, 1);
+ 2 var otherChars = cityToCheck.slice(1);
+ 3 firstChar = firstChar.toUpperCase();
+ 4 otherChars = otherChars.toLowerCase();
+ 5 var cappedCity = firstChar + otherChars;
+ Here's what happens in the code above, line-by-line:
+ 1. Copies the first character of the string and assigns it to the
+ variable firstChar.
+ 2. Copies all the characters from the second one to the end and assigns
+ them to the variable
+ otherChars.
+ 3. Caps the first character.
+ 4. Lower-cases the other characters.
+ 5. Concatenates both parts to re-form the whole string.
+ Sometimes it's useful to know how many characters are in a string. For
+ example, suppose
+ you want to slice the first three characters from any string than
+ exceeds three characters in
+ length, for example, slicing "Nov" from "November". To find the number
+ of characters in a
+ string, you use the same language you've already learned to find the
+ number of elements in an
+ array.
+ 1 var month = prompt("Enter a month");
+ 2 var charsInMonth = month.length;
+ 3 if (charsInMonth > 3) {
+ 4 monthAbbrev = month.slice(0, 3);
+ 5 }
+ Line 2 counts the characters in the string and assigns the number to the
+ variable
+ charsInMonth.
+ Being able to measure the number of characters in a string can come in
+ handy. For
+ example, suppose you want to loop through a string, checking to see if
+ it has any double spaces
+ in it. You can use the character count as the loop limiter. Here's some
+ code that checks for
+ double spaces in a string and displays an alert if they're found.
+ 1 var str = prompt("Enter some text");
+ 2 var numChars = str.length;
+ 3 for (var i = 0; i < numChars; i++) {
+ 4 if (str.slice(i, i + 2) === " ") {
+ 5 alert("No double spaces!");
+ 6 break;
+ 7 }
+ 8 }
+ Line 2 counts the number of characters in the string and assigns the
+ number to the variable
+ numChars. In line 3, this number is used as the loop limiter. The loop
+ continues to run only as
+ long as the counter, i, is less than the number of characters in the
+ string. (Remember, the length
+ is 1-based, and the counter is 0-based, so the loop has to stop 1 short
+ of the length number.)
+ Line 4 moves through the string character-by-character, examining each
+ 2-character segment,
+ looking for double spaces.
+
+ The New Yorker magazine doesn't allow the phrase "World War II. " They
+ say it should
+ be "the Second World War." So let's search the following sentence for
+ the banned characters
+ and replace them with the phrase that the New Yorker prefers.
+ It is startling to think that, even in the darkest depths of World War
+ II, J. R. R. Tolkien was
+ writing the trilogy, which contains, with the weird applicability
+ available only to poetry and
+ myth, the essential notion that the good gray wizard can understand the
+ evil magi precisely
+ because he is just enough like them to grasp their minds and motives in
+ ways that they cannot
+ grasp his.
+ You already know a way to find the banned segment and replace it.
+ Suppose the
+ paragraph above has been assigned to the variable text.
+ 1 for (var i = 0; i < text.length; i++) {
+ 2 if (text.slice(i, i + 12) === "World War II") {
+ 3 text = text.slice(0, i) + "the Second World War" + text.slice(i + 12);
+
+ 4 }
+ 5 }
+ The code loops through the string looking for "World War II." Line 2
+ progresses through
+ the string character-by-character, examining each 12-character sequence.
+ If it finds "World
+ War II," line 3 concatenates three segments: all the characters
+ preceding "World War II," the
+ substitute phrase "the Second World War," and then all the characters
+ following "World War
+ II."
+ But JavaScript has a more efficient way to accomplish this, using the
+ indexOf method.
+ var firstChar = text.indexOf("World War II");
+ If the segment exists, the method finds the index of the first character
+ of the segment and
+ assigns it to the variable firstChar. If the segment doesn't exist, the
+ method assigns -1 to the
+ variable, so you know it's not there.
+ Now we can replace the banned phrase with the preferred phrase with less
+ coding.
+ 1 var firstChar = text.indexOf("World War II");
+ 2 if (firstChar !== -1) {
+ 3 text = text.slice(0, firstChar) + "the Second World War" +
+ text.slice(firstChar + 12);
+ 4 {
+ Line 1 checks for the phrase, assigning the index of the first character
+ of the phrase to the
+ variable firstChar—if the phrase is found. If it isn't found, -1 is
+ assigned to the variable. If
+ the variable doesn't have the value -1 (line 2)—if the phrase has been
+ found—the
+ concatenation in line 3 replaces the offending phrase with the correct
+ pharse.
+ The indexOf method finds only the first instance of the segment you're
+ looking for. In the
+ example above, you could overcome this limitation by looping. You'd
+ change the first instanc
+ of "World War II" to "the Second World War," then in the next loop
+ iteration, find the next
+ surviving instance and change that, and so on.
+ To find the last instance of a segment in a string, use lastIndexOf. The
+ following code
+ finds the index of the first character of the last instance of the
+ segment, the second "be". The
+ variable segIndex winds up with a value of 16, the index of "b" in the
+ second "be".
+ 1 var text = "To be or not to be.";
+ 2 var segIndex = text.lastIndexOf("be");
+
+ The user has entered his first name. The string has been assigned to the
+ variable
+ firstName. You want to extract the first character. You already know one
+ way to do it.
+ var firstChar = firstName.slice(0, 1);
+ Here's an alternate way to do it that's more direct.
+ var firstChar = firstName.charAt(0)
+ The code above finds a single character at index-0 (the beginning) of
+ the string
+ represented by the variable firstName and assigns it to the variable
+ firstChar.
+ The following code finds the last character in the string.
+ var lastChar = name.charAt(name.length - 1);
+ The following code cycles through a string looking for an exclamation
+ point. If the
+ character is found, an alert displays.
+ 1 for (var i = 0; i < text.length; i++) {
+ 2 if (text.charAt(i) === "!") {
+ 3 alert("Exclamation point found!");
+ 4 break;
+ 5 }
+ 6 }
+ Note: The indexOf method can only identify the character at a particular
+ location. It can't
+ change the character at a location.
+
+ In previous chapters you learned two different ways to replace "World
+ War II" with "the
+ Second World War" in a string. First, there was the loop-and-slice
+ approach.
+ 1 for (var i = 0; i < text.length; i++) {
+ 2 if (text.slice(i, i + 12) === "World War II") {
+ 3 text = text.slice(0, 1) + "the Second World War" + text.slice(i + 12);
+
+ 4 }
+ 5 }
+ You improved on that rather crude approach when you learned the indexOf
+ method.
+ 1 var firstChar = text.indexOf("World War II");
+ 2 if (firstChar !== -1) {
+ 3 text = text.slice(0, firstChar) + "the Second World War" +
+ text.slice(firstChar + 12)
; 4 }
+ But JavaScript provides a more straightforward way still, the replace
+ method.
+ var newText = text.replace("World War II", "the Second World War");
+
+ The first string inside the parentheses is the segment to be replaced.
+ The second string is
+ the segment to be inserted. In the above code, the segment "World War
+ II" is replaced by the
+ segment "the Second World War" in the string represented by the variable
+ text, and the
+ revised string is assigned to the new variable newText.
+ If you assign the revised string to a new variable, as in the example
+ above, the original
+ string is preserved. If you want the original string to be replaced by
+ the revised string, assign
+ the revised string to the original variable.
+ text = text.replace("World War II", "the Second World War");
+ In the examples above, only the first instance of a string is replaced.
+ If you want to
+ replace all instances, you must let JavaScript know that you want a
+ global replace.
+ var newText = text.replace(/World War II/g, "the Second World War");
+
+ In a global replace, you enclose the segment to be replaced by slashes
+ instead of
+ quotation marks, and follow the closing slash with "g" for "global." The
+ segment to be inserted
+ is enclosed by quotation marks, as in a one-time replace.
+
+ +
+