The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
SlightlyLoony
Tera Contributor

Our young developer has just discovered that her boss has been keeping secrets from her. All this time in her (extensive) JavaScript programming experience, she's believed that arrays were places where you could store lists of like things. You could have an array of numbers, for example, or an array of strings. And certainly her boss never told her that you could use an array like a stack, or rotate the elements in it, or reverse their order, or any number of other nifty things.

This morning she discovered that arrays were cool. Who knew? And now she's raging...

The Array object is so cool that it's hard for your blogger to know where to start. I guess first we'll just clear up a common misconception: that arrays can only be used to store things of the same type. Consider this code:


var a = [152,'test',true,null,{test:'xxx',there:'yyy'}];
JSUtil.logObject(a);

The square brackets are a shorthand for creating an instance of the JavaScript Array class. In between those square brackets, we've got five literal values, separated by commas. Note that the literal values are all different types — JavaScript's dynamic typing makes this possible. You can stuff any combination of types you'd like to into any array. Here's what was logged when we ran it:

Log Object
Array of 5 elements
[0]: number = 152
[1]: string = test
[2]: boolean = true
[3]: null = null
[4]: Object
there: string = yyy
test: string = xxx

A "stack", more formally, is a last-in, first-out (LIFO) data structure. JavaScript arrays have two methods (push() and pop()) that let you use an array as if it was a LIFO data structure, or stack. Consider:

var a = [];
a.push(55);
a.push(83);
a.push(29);
gs.log('Size: ' + a.length);
gs.log(a.pop());
gs.log(a.pop());
gs.log(a.pop());
gs.log('Size: ' + a.length);
gs.log(a.pop());

When we run this code, it will create the array a, push three numbers onto it (treating it like a stack), print the length (which is 3 because we pushed three numbers), then pops and prints three numbers. Note that they're printed in reverse of the order they were pushed, and when we're done the length is zero. But then the code tries to pop a fourth value off — and look what happens:

Size: 3
29
83
55
Size: 0
undefined

That undefined value is a good indication that your code is doing something silly — it doesn't make any sense to pop more things off a stack than you pushed onto it!

If you're familiar with data structures in general, you might be wondering if you can make a first-in, first out (FIFO) data structure with a JavaScript array. Of course you can! Here's a simple example by a small tweak in the preceding code:

var a = [];
a.push(55);
a.push(83);
a.push(29);
gs.log('Size: ' + a.length);
gs.log(a.shift());
gs.log(a.shift());
gs.log(a.shift());
gs.log('Size: ' + a.length);
gs.log(a.shift());

The result is just like the last example, except that the order of elements shifted off is the same as the order of elements pushed on:

Size: 3
55
83
29
Size: 0
undefined

Got that? Let's see if you can figure this one out:

var a = [55,83,29];
gs.log(a);
a.push(a.shift());
gs.log(a);
a.unshift(a.pop());
gs.log(a);
a.unshift(a.pop());
gs.log(a);
a.push(a.shift());
gs.log(a);

That code first builds the same array of three values we've been playing with, then does a "rotate left" operation (the a.push(a.shift()) line) by shifting off the first (leftmost) value and pushing it back on as the last (rightmost) value. The next line rotates right, which puts the array back in the same state it started out. The next two lines do the same thing, but in the reverse order. Is your head spinning yet?

55,83,29
83,29,55
55,83,29
29,55,83
55,83,29

We're not done yet - arrays have a few more tricks yet! Here's a simple one:

var a = [55,83,29];
gs.log(a);
a.reverse();
gs.log(a);
a.reverse();
gs.log(a);

You can probably guess what that does:

55,83,29
29,83,55
55,83,29

Once you have an array, the slice() method gives you very flexible ways of getting any piece of it you want, by specifying the first element of the array you want and (optionally) the element after the last one you want. If you leave out the second argument, it will return all the elements to the end of the array. Negative arguments count elements from the end (right), instead of from the beginning (left):

var a = [55,83,29,76,14];
gs.log(a);
var b = a.slice(1,3);
gs.log(b);
b = a.slice(-2,1);
gs.log(b);
b = a.slice(-2,-1);
gs.log(b);
b = a.slice(-2);
gs.log(b);

When the arguments are negative, it means the count of positions from the right side instead of from the left side for positive numbers.

55,83,29,76,14
83,29

76
76,14

Study that until it all makes sense to you. The third one is blank (empty array) because the line a.slice(-2,1) is specifying a last element that's before the first element.

Here's one last method for you: splice(). This method is very powerful — it can simultaneously insert elements into, and delete elements from, an array. The first argument specifies the element position where the insertion and deletion is to occur. Just like with slice(), if this argument is negative, it means you're counting from the end (right) position. The second argument specifies how many elements should be deleted. If you don't want to delete any elements, just put a zero there. The remaining arguments specify the values to be inserted after any deletions, at the same position. There's a tricky bit to that: if you specify an array as one of these arguments, the array itself is not inserted, but rather its elements. Finally, the method returns an array of any elements deleted. Phew! Some examples might make all this easier to understand, but you'll probably need to stare at them for a while:

var a = [55,83,29,76,14];
gs.log(a);
var b = a.splice(2, 0, 71, 72, 73);
gs.log(a + " : " + b);
b = a.splice(2, 3, [99,98]);
gs.log(a + " : " + b);
b = a.splice(-5, 3, [68,67,66]);
gs.log(a + " : " + b);
b = a.splice(1, 4, [51,52],53,[54,55]);
gs.log(a + " : " + b);

When we ran this, we got:

55,83,29,76,14
55,83,71,72,73,29,76,14 :
55,83,99,98,29,76,14 : 71,72,73
55,68,67,66,76,14 : 83,99,98,29
55,51,52,53,54,55 : 68,67,66,76,14

Now you see why our young lady is raging!

W3Schools has a nice reference for the JavaScript Array object online...