Use the shift method to remove an element from the beginning of an
array.
Suppose you have an array, pets, whose elements are "dog", "cat", and
"bird". The
following removes the first element, "dog", leaving you with a
two-element array.
pets.shift();
To add one or more elements to the beginning of an array, use the
unshift method.
The following code adds two elements to the beginning of the array.
pets.unshift("fish", "ferret");
Use the splice method to insert one or more elements anywhere in an
array, while
optionally removing one or more elements that come after it. Suppose you
have an array with
the elements "dog", "cat", "fly", "bug", "ox". The following code adds
"pig", "duck", and "emu"
after "cat" while removing "fly" and "bug".
pets.splice(2, 2, "pig", "duck", "emu");
The first digit inside the parentheses is the index of the position
where you want to start
adding if you're adding and deleting if you're deleting. The second
digit is the number of
existing elements to remove, starting with the first element that comes
after the element(s) that
you're splicing in. The code above leaves you with an array consisting
of "dog", "cat", "pig",
"duck", "emu", and "ox".
You could make additions without removing any elements. The following
code adds
"pig", "duck", and "emu" without removing any elements.
pets.splice(2, 0, "pig", "duck", "emu");
You can also remove elements without adding any. If you start with the
elements "dog",
"cat", "fly", "bug", and "ox", the following code removes two elements
starting at index 3
—"bug" and "ox". This leaves "dog", "cat", and "fly".
pets.splice(2, 2);
Use the slice method to copy one or more consecutive elements in any
position and put
them into a new array. If you start with an array, pets, consisting of
"dog", "cat", "fly", "bug",
and "ox", the following code copies "fly" and "bug" to the new array
noPets and leaves the
original array, pets, unchanged.
var noPets = pets.slice(2, 4);
The first digit inside the parentheses is the index of the first element
to be copied. The
second digit is the index of the element after the last element to be
copied.
Two things could trip you up here:
Since the first index number inside the parentheses specifies the first
element to be
copied, you might think the second index number specifies the last
element to be copied.
In fact, the second number specifies the index number of the element
after the last element
to be copied.
You must assign the sliced elements to an array. It could, of course, be
the same array
from which you're doing the slicing. In that case, you'd be reducing the
original array to
only the copied elements.
You know the song "99 Bottles of Beer on the Wall"? If you're teaching
someone the song,
you could give them these instructions:
1. Sing "99 bottles of beer on the wall, 99 bottles of beer."
2. Sing "Take one down and pass it around, 98 bottles of beer on the
wall."
3. Sing "98 bottles of beer on the wall, 98 bottles of beer."
4. Sing "Take one down and pass it around, 97 bottles of beer on the
wall."
5. Sing "97 bottles of beer on the wall, 97 bottles of beer."
6. Sing "Take one down and pass it around, 96 bottles of beer on the
wall."
...and so on, for 192 more lines of instructions.
But that isn't how you'd give the instructions, is it? You'd be more
concise. You'd say
something like this:
Sing "99 bottles of beer on the wall, 99 bottles of beer. Take one down
and pass it
around, 98 bottles of beer on the wall." Repeat this, subtracting 1 each
time, until there are no
more bottles of beer on the wall.
In coding, you run into the bottles-of-beer situation quite often. For
example, suppose
you've offered to check if the user's city is one of the 5 cleanest in
the U.S. The user has
entered her city, and you've assigned her city to the variable
cityToCheck.
You've already assigned the list of the 5 cleanest cities to the array
cleanestCities.
var cleanestCities = ["Cheyenne", "Santa Fe", "Tucson", "Great Falls",
"Honolulu"];
Now you go through the array to see if there's a match with the user's
city. If there is, you
display an alert telling the user her city is one of the cleanest. If
there's no match, you display
an alert telling the user her city isn't on the list.
1 if (cityToCheck === cleanestCities[0]) {
2 alert("It's one of the cleanest cities");
3 }
4 else if (cityToCheck === cleanestCities[1]) {
5 alert("It's one of the cleanest cities");
6 }
7 else if (cityToCheck === cleanestCities[2]) {
8 alert("It's one of the cleanest cities");
9 }
10 else if (cityToCheck === cleanestCities[3]) {
11 alert("It's one of the cleanest cities");
12 }
13 else if (cityToCheck === cleanestCities[4]) {
14 alert("It's one of the cleanest cities");
15 }
60
16 else {
17 alert("It's not on the list");
18 }
Conveniently, JavaScript provides a more concise coding approach. Here's
a for loop
that accomplishes most of what the verbose code in the example above
accomplishes.
1 for (var i = 0; i <= 4; i++) {
2 if (cityToCheck === cleanestCities[i]) {
3 alert("It's one of the cleanest cities");
4 }
5 }
Let me break down the first line for you.
The first line begins with the keyword for.
The three specifications that define the loop are inside the
parentheses.
1. A variable that counts iterations and also serves as the changing
array index is declared
and set to a starting value, in this case 0.
2. The limit on the loop is defined. In this case, the loop is to keep
running as long as the
counter doesn't exceed 4. Since the counter, in this case, is starting
at 0, the loop will run
5 times.
3. What happens to the counter at the end of every loop. In this case,
the counter is
incremented each time.
The three specifications inside the parentheses are always in the same
order:
1. What to call the counter (usually i) and what number to start it at
(typically 0)
2. How many loops to run (in this case, the number of elements in the
array)
3. How to change the counter after each iteration (typically to add 1
each time through)
Things to keep in mind:
In the example, the counter, i, serves two purposes. It keeps track of
the number of
iterations so looping can halt at the right point. And it serves as the
index number of the
array, allowing the code to progress through all the elements of the
array as the counter
increments with each iteration.
There is nothing sacred about using i as the counter. You can use any
legal variable
name. But coders usually use i because it keeps the first line compact,
and because
coders understand that i stands for "iteration."
In the example, the initial count is 0, the index number of the first
element of the array.But
it could be any number, depending on your needs.
In the example, the counter increments with each iteration. But,
depending on your needs,
you can decrement it, increase it by 2, or change it in some other way
each time through.
In the example, I specify that the loop is to run as long as i <= 4.
Alternatively, I could
have specified i < 5. Either way, since the counter starts at 0, the
loop runs 5 times.
There are several problems with the for loop example I gave you in the
last chapter. The
first problem is a potential communication problem. If a match between
the user's city and the
list of cleanest cities is found, a confirming alert displays. But if
there is no match, nothing
happens. The user is left in the dark. If no match is found, we need to
display an alert saying
so. But how do we do that?
We do it with a flag. A flag is just a variable that starts out with a
default value that you
give it, and then is switched to a different value under certain
conditions. In our example, let's
say this is the flag.
var matchFound = "no";
If a match is found, the value of the flag is changed. At the end, if
the flag hasn't been
changed—if it still has the original value of "no"—it means no match was
found, and so we
display an alert saying the city isn't on the list.
1 var matchFound = "no";
2 for (var i = 0; i <= 4; i++);
3 if (cityToCheck === cleanestCities[i]) {
4 matchFound = "yes";
5 alert("It's one of the cleanest cities");
6 }
7 }
8 if (matchFound === "no") {
9 alert("It's not on the list");
10 }
This works, but rather than assigning the strings "no" and "yes" to the
switch, it's
conventional to use the Boolean values false and true.
1 var matchFound = false;
2 for (var i = 0; i <= 4; i++);
3 if (cityToCheck === cleanestCities[i]) {
4 matchFound = true;
5 alert("It's one of the cleanest cities");
6 }
7 }
8 if (matchFound === false) {
9 alert("It's not on the list");
10 }
There are only two Booleans, true and false. Note that they aren't
enclosed in quotes.
The next problem with our example is that it potentially wastes
computing cycles.
Suppose on the second loop a match is found and the alert displays. The
way the loop is
coded, the loop goes on looping all the way to the end. This is
unnecessary, since we got our
answer in the second loop. The problem is solved with the keyword break.
1 var matchFound = false;
2 for (var i = 0; i <= 4; i++);
3 if (cityToCheck === cleanestCities[i]) {
4 matchFound = true;
5 alert("It's one of the cleanest cities");
6 break;
7 }
8 }
9 if (matchFound === false) {
10 alert("It's not on the list");
11 }
The last problem: In the example, I assume that the number of elements
in the array is
known. But what if it isn't? JavaScript has a way of finding out. The
following code assigns the
number of elements in the array cleanestCities to the variable
numElements.
var numElements = cleanestCities.length;
Now we can limit the number of loops to the count that JavaScript comes
up with.
1 var numElements = cleanestCities.length;
2 var matchFound = false;
3 for (var i = 0; i < numElements; i++);
4 if (cityToCheck === cleanestCities[i]) {
5 matchFound = true;
6 alert("It's one of the cleanest cities");
7 break;
8 }
9 }
10 if (matchFound === false) {
11 alert("It's not on the list");
12 }
Now the loop keeps going as long as i is less than the number of
elements. (Since the
length number is 1-based and the i number is 0-based, we need to stop 1
short of the length.)
Atlantic Records has hired you and me to generate a list of names for
future rap stars. To
make things easy, we'll start by making separate lists of some first
names and last names.
By combining each of the first names with each of the last names, we can
generate 20
different full names for rappers.
Starting with "BlueRay," we go through the list of last names,
generating...
BlueRay Zzz
BlueRay Burp
BlueRay Dogbone
BlueRay Droop
We move to the next first name, "Upchuck." Again, we go through the list
of last names,
generating...
Upchuck Zzz
Upchuck Burp
Upchuck Dogbone
Upchuck Droop
And so on, combining each first name with each last name.
But look, why not have JavaScript do the repetitive work? We'll use
nested for
statements.
1 var firstNames = ["BlueRay ", "Upchuck ", "Lojack ", "Gizmo ", "Do-Rag
"];
2 var lastNames = ["Zzz", "Burp", "Dogbone", "Droop"];
3 var fullNames = [];
5 for (var i = 0; i < firstNames.length; i++) {
6 for (var j = 0; j < lastNames.length; j++) {
7 fullNames.push(firstNames[i] + lastNames[j]);
67
9 }
10 }
Things to think about:
The inner loop runs a complete cycle of iterations on each iteration of
the outer loop. If
the outer loop counter is i and the inner loop counter is j, j will loop
through 0, 1, 2, and
all the way to the end while i is on 0. Then i will increment to 1, and
j will loop through
all of its values again. The outer loop is the minute hand of a clock.
The inner loop is the
second hand.
You can have as many levels of nesting as you like.
A nested loop is indented 2 spaces beyond its outer loop.