Looking for the previous guiStuff?
It's still here, the content didn't go anywhere. You may want to check out this new guiStuff though -- It's rather informative.
References/Tutorials:
Intro Documents:
guiStuff:
::Stuff for the multi-spec coder;
Coding, formats, standards, and other practical things.
<!-- JavaScript
Arrays: Part 2 - Array Methods 1
In Part 1 of JavaScript Arrays, we covered the basics of declaring and assigning Arrays. This article is the first of two that will deal with Array Methods.The Methods that are provided to you by the Array class can be devided into two categories: Array Methods, and Array/String Methods. I'll cover the Array methods first, with the exception of two String/Array methods that are both simple and very useful to the learning process, which I'll start off with:
valueOf(), and toString().valueOf() and toString()
All Objects in JavaScript have thevalueOf() and toString() methods, they're simply Common Object Methods. In Arrays, however, the two methods have been 're-tasked' (technically, they've been overridden). These two methods, in the Array class, are identical in their function: they both call the toString() method for each individual element within the Array, and concatenates these values together, separated by commas. This is unique in the sense that it makes these methods useful almost exlusively for testing/validation purposes, but don't worry, by the time you go over the String/Array methods, you'll have plenty of flexibility to do anything you want with Strings within your Arrays.Here's how the
toString() method works:
var myArr = new Array("Alpha", "Beta", "Gamma"); // The Array contains 3 Strings
alert(myArr.toString()); // alerts 'Alpha,Beta,Gamma'
If you were to replace
toString() with valueOf(), you'd get the same result. I'll use this method frequently from now on to 'probe' the Arrays we deal with. When dealing with Arrays that contain Strings, you'll want to keep this/these method/s (it's the same method, really) handy and check to see what your Arrays are made up of along the way. Along with the length property, the two make very good built-in debugging tools.You may be wondering what would happen if you used this on an Array that contained uninitialized values:
var myArr = new Array(1, 2, 3); // The Array contains 3 Number Primitives
myArr[9] = 10;
alert(myArr.toString()); // alerts '1,2,3,,,,,,,10'
As you can see, it's like taking any uninitialized String and using the
toString() method on it: you get an empty String. Note that I placed Number Literals in this Array, which means that the toString() method had to actually convert them to Strings, instead of just handing over the values as it does with String values.concat()
You'll recognize this method's name from the String class, and you'll also see the resemblance in their function. Theconcat() method in the Array class takes the argument/s, appends it/them to the end of the Array, and returns a new Array object containing the result:
var myArr = new Array("Alpha", "Beta", "Gamma");
alert(myArr.toString()); // alerts 'Alpha,Beta,Gamma'
var myArr2 = myArr.concat("Delta", "Epsilon");
alert(myArr.toString()); // alerts 'Alpha,Beta,Gamma'
alert(myArr2.toString()); // alerts 'Alpha,Beta,Gamma,Delta,Epsilon'
We first create a new Array and assign three Strings to it. We then 'probe' it using the
toString() method to see what's in it, and we get what we expect. Now, we call concat() and hand it two String values as arguments, where our original Array is the one to concatenate them to. The expression myArr.concat("Delta", "Epsilon"); actually creates a new Array object right there, and thus is expecting us to assign it to a variable, which we do -- namely, to myArr2. At this point, we check to see that our original Array hasn't been modified by this action, and it hasn't. The last line in the script finally checks the result of the whole process and checks the values within the newly created array, myArr2, to see that it indeed appended the two additional String values to the end of the original Array's values.Already, this shows us the great potency of the
concat() method: It takes an arbitrary number of values of any data type. This can be used to append Strings, Number Literals, variables, Objects, and even other Arrays. Speaking of other Arrays, let's see concat() work its magic with multiple Arrays:
var myArr = ["Alpha", "Beta", "Gamma"];
var myArr2 = ["Delta", "Epsilon", "Zeta"];
alert(myArr.concat(myArr2).toString()); // alerts 'Alpha,Beta,Gamma,Delta,Epsilon,Zeta'
You may have noticed that I've taken the liberty to take a few shortcuts this last script. First, I used bracket notation to declate and assign the first two Arrays. Then, when I used
concat() to concatenate the two Arrays, not only did I place toString() right to its result, but I passed toString()'s result right to the alert function as an argument. This means that, first, the newly created Array has been lost (the Array Object was not stored anywhere), and second, the resulting String, once given as an argument to alert, also 'went nowhere' (that is, it was not stored as a String anywhere). You'd be surprized how often syntax like this is used when testing code, since it leaves no trace or trail of variables, and it doesn't effect the objects involved (niether of the Arrays have been modified).Meanwhile, to what actually took place here,
concat() was given an Array object as an argument this time. As mentioned above, this does not present a problem for it. It tooks the values within this Array, and appended them to the original one, to create a new Array Object containing the resulting values. This is incredibly useful when dealing with multiple Arrays, since it's intuitive, and gives you the ability to move their contents around freely (when combined with additional methods described below).You can also use
concat() to place Arrays within Arrays, or Multi-Dimentional Arrays. This specific aspect won't be covered in this article, since it requires specific attention to nesting elements, and how various Array methods deal with them.slice()
Another method you'll recognize from the String class is theslice() method. In the Array class, the slice() method operates in a somewhat similar fashion to the String.slice() method, in the sense that it extracts a sub-section of the Array and presents it as a new Array for assignment. The slice() method accepts one or two arguments, both integers (which may be negative). If it is given one argument, the argument will serve as the index at which slice() begins to select elements of the Array, and it will continue to select elements until the end of the Array, returning a new Array containing these selected elements. If it is given two arguments, it will start selecting elements at the first argument (the argument, again, serving as the index), and stop selecting at the second argument. The second index position is not included in the resulting array, much like in the String.slice() method.In other words, it's:
slice( from , to, but not including ).Here's
slice() in action:
var myArr = ["Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta"];
var mySlice1 = myArr.slice(2);
var mySlice2 = myArr.slice(1, 4);
alert(mySlice1.toString()); // alerts 'Gamma,Delta,Epsilon,Zeta'
alert(mySlice2.toString()); // alerts 'Beta,Gamma,Delta'
The first call to
slice() was given one argument, the start position. This made it 'select' elements from index 2 of the Array, through to its end, returning four elements. The second call to slice() was given both from and to arguments, which made it start selecting at index 1, and stop selecting at index 4, but not include the element at index 4, and return three elements: 'Beta,Gamma,Delta'. Just like the String.slice() method does not efect the String it's applied to, the Array.slice() method does not effect the Array it's applied to, but rather returns a new one.You can also pass
slice() negative arguments, and, just like in String.slice(), it will then 'count' Array elements from the end of the Array. This means that -1 translates into myArray.length-1 within slice(). This is convenient when you want to 'clip off' n elements from the end of an Array, for example.Here are some negative
slice() arguments in practice:
var myArr = ["Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta"];
// select the last two elements of the Array:
var mySlice1 = myArr.slice(-2);
// select all but the first and last elements of the Array:
var mySlice2 = myArr.slice(1, -1);
// select from the 3rd to last, to (but not including) the last element:
var mySlice3 = myArr.slice(-3, -1);
alert(mySlice1.toString()); // alerts 'Epsilon,Zeta'
alert(mySlice2.toString()); // alerts 'Beta,Gamma,Delta,Epsilon'
alert(mySlice3.toString()); // alerts 'Delta,Epsilon'
The first
slice() basically translates, in the case of this Array, into slice(4), returning the last two elements. The second gets both a positive and a negative argument, that translate to slice(1, 5), and return the original Array minus the first and the last elements (which is why seeing it as (1, -1) is more visually representative). The last slice() effectively looks for the 3rd and 2nd elements from the end of the Array, and in this instance translates to slice(3, 5).reverse()
Thereverse() method simply reverses the order of elements in an Array. This method differs from the Array methods we've seen so far in that it does not return a new Array, but rather reverses the elements in the Array it is applied to -- it effects the contents of the Array to which it's applied.Here's an example:
var myArr = ["Alpha", "Beta", "Gamma", "Delta"];
alert(myArr.toString()); // alerts 'Alpha,Beta,Gamma,Delta'
myArr.reverse();
alert(myArr.toString()); // alerts 'Delta,Gamma,Beta,Alpha'
As you can see, no new Arrays were created here beyond the initial one. The
reverse() method reversed the order of the elements within that Array. The action was taken "in place". Using reverse() is often used in sorting scripts where you may want to sort a list of names alphabetically, and then you decide that you want to look at the list from end-to-beginning. The same could happen with Dates, or numeric values.push() and pop()
At this point, we begin to see methods that allow you to use Arrays as various Data Structures. These methods, at least as far as their function goes, may simply seem "useful and interesting", but they're here for more than just what they do independantly. They're here to work with each other, along with other methods, to allow you to create Arrays that operate like mechanisms which you can use to structure (verb.) your data.We'll get to these abstract uses later, first we'll cover the actual methods and their functions.
First of all, both
push() and pop() are in-place methods, just like reverse(). This means that they do not return new Array Objects, but rather act on the Array on which they're applied. The push() method takes an arbitrary number of arguments, just like concat(), and appends them to the end of the Array. Unlike concat(), it does this to the Array itself, instead of returning a new Array Object. It also returns a value: the new length of the Array.The
pop() method does the reverse (not exactly, but virtually): it removed the last element in the Array, and reduces the length of the Array by 1. The pop() method takes no arguments, and always removes only one element. It also returns a value: it returns the value of the element it just removed.This is very useful in practice, and here's where you start seeing the structuring of data take place: You can create a 'stack' structure, like an inbox. You start off with an empty Array, we'll call it "Inbox", and say it's empty at first. Gradually, you append elements using the
push() method. The Inbox grows as items (elements, but we're talking abstractly here...) are added. When you want to process elements, you pop() them off, automatically reducing the size of the Array as you do so, and getting each element's value in order to process it. The Array is 'managed' by the two functions. As a data structure, this is called a Last-In-First-Out (LIFO) structure, and can help you manage all sorts of scenarios.Let's see this in action:
var Stack = [];
alert(Stack.push("Hydrogen", "Helium", "Lithium")); // alerts 3
alert(Stack.toString()); // alerts 'Hydrogen,Helium,Lithium'
alert(Stack.pop()); // alerts 'Lithium'
alert(Stack.toString()); // alerts 'Hydrogen,Helium'
alert(Stack.push("Beryllium", "Boron")); // alerts 4
alert(Stack.toString()); // alerts 'Hydrogen,Helium,Beryllium,Boron'
alert(Stack.pop()); // alerts 'Boron'
alert(Stack.pop()); // alerts 'Beryllium'
alert(Stack.length); // alerts 2
This is actually rather intuitive when you get used to it. Think of it as adding items to a stack and removing them from that stack. First, an empty Array (incidentally, called
Stack) is created. Then, three elements (Get it?... Elements?... Well I thought it was funny...) are 'pushed' onto the Array and the push() method returns the new length of the Array, which is 3. The toString() is used to keep track of the contents of the Array as it's modified. At this point, one element is pop()ed and alerted. Now, two more elements are push()ed, making the Array length increase to 4, which push() notifies us of. Lastly, two pop()s are used to remove the last two elements of the Array and return their values, leaving a two-element Array.This was a simple example of a LIFO (Last-In-First-Out) implementation. Before we can cover more strcutures we'll need two more functions, that are coming right up.
unshift() and shift()
Theunshift() and shift() methods are very similar to the push() and pop() methods, except that they act on the beginning of the Array, rather than the end of it. Think of it like a coin dispenser, you can place it in any angle: imagine it's been placed where the coins are placed, and removed, from the bottom, rather than the top. When you're adding items/elements, you're 'pushing' the entire contents of the Array 'upwards'. If you've added one element using unshift(), you've placed it at index 0, and incremented all of the rest of the Array indexes by one. Also, like push(), you've automatically increased the Array's length to accomodate the newly added item/s / element/s.When you
shift() an Array, you remove the element at the first index of the Array, and decrement the rest of the the Array's indexes by one. As well, shift() will reduce the length of the Array by one automatically, and, just like pop(), return the value of the removed element.To help with mnemonics a bit, think of the word 'shift' as "to move" something, or in this case, remove something, making
shift() the equivalent of pop() on the other side. To 'unshift' might be thought of as "un-move", or rather, "re-place", making it the equivalent of push(), again, on the other side. Even if this doesn't help much, you'll get used to them when you've used them a bit.Here's a similar example from before, this time with
unshift() and shift():
var Stack = [];
alert(Stack.unshift("Hydrogen", "Helium", "Lithium")); // alerts 3
alert(Stack.toString()); // alerts 'Hydrogen,Helium,Lithium'
alert(Stack.shift()); // alerts 'Hydrogen'
alert(Stack.toString()); // alerts 'Helium,Lithium'
alert(Stack.unshift("Beryllium", "Boron")); // alerts 4
alert(Stack.toString()); // alerts 'Beryllium,Boron,Helium,Lithium'
alert(Stack.shift()); // alerts 'Beryllium'
alert(Stack.shift()); // alerts 'Boron'
alert(Stack.length); // alerts 2
This is the exact example as the previous one, except
push() was replaced with unshift() and pop() was replaced with shift(). The result is that all of the operations happened at the begining of the stack, rather than the end of it. This is not strictly a structure, in fact you'd be hard pressed to find a use for it, since as you can see, the order of elements is unpredictable when you're unshift()ing more than one. However, when the four methods are combined, you can create very diverse structures.The first example of a common structure you can create is a Queue, also referred to as a Last-In-Last-Out (or LILO) structure. This is usually visualized by people waiting in line: The first person who arrived will be the first person who will receive service, whereas the last person to arrive will have to wait for the rest of the people in line to 'be processed' until it's his turn. Hence - Last-in, Last-out.
Which methods would you use to emulate this? Well, people arrive at the end of the line, meaning that
push() would fill that need. And the first person in the line is the one who's going to be serviced, so shift(), which deals with index 0, would handle that nicely.There are still many Array Methods remaining, many of which handle Strings, and there are numerous Array structures and 'stratrgies' to cover.
These will be covered in Part 3.
Return to the JavaScript section, or go the to Main page.