Mastering Javascript Arrays

標簽: 瀏覽(13708)  日期:2007-05-29

Mastering Javascript Arrays

Filed: Sun, Mar 25 2007 under Programming|| Tags: reference arrays javascript stacks queues ajax

Mastering Javascript Arrays

Believe it or not, the very first version of Javascript shipped without Arrays. Subsequent versions made up for the oversight and modern Javascript Arrays are powerful structures indeed, even emulating many common data structures such as stacks and queues. This reference will cover the core functionality of Arrays as well as introduce a few useful extensions.

Introduction

An Array is an enumerated list of variables. It`s a programming construct that allows programmers to replace this…

x0=0;x1=1;x2=2;x3=3;x4=4;x5=5;

…with this…

x[0]=0;x[1]=1;x[2]=2;x[3]=3;x[4]=4;x[5]=5;

The index (the number in the brackets [] )can be referenced by a variable, allowing for easy looping through the data structure.

for(i=0; i<6; i++) {    document.writeln(x[i]+`<br>); }

Which will output the following…

012345

Creating A New Array

Most tutorials start out introducing you to arrays as such…

var myArray = new Array(10);

Current best-practice eschews the “new” keyword on Javascript primitives. If you want to create a new Array simply use brackets [] like this…

var myArray = [];

You don`t need to tell Javascript how many items to size the Array for. Javascript will automatically increase the size of the Array as needed, as you add items into the Array. Creating an Array with brackets instead of with the “new” constructor avoids a bit of confusion where you want to initialize only one integer. For instance.

var badArray = new Array(10); // Creates an empty Array that`s sized for 10 elements.
var goodArray= [10];          // Creates an Array with 10 as the first element.

As you can see these two lines do two very different things. If you had wanted to add more than one item then badArray would be initialized correctly since Javascript would then be smart enough to know that you were initializing the array instead of stating how many elements you wanted to add.

Since the new constructor is not necessary with Arrays and there`s a slight chance of unintended results by using the new constructor, it`s recommended you not use “new Array()” to create an Array.

Initializing An Array

You can initialize your array with pre-defined data…

var myArray = [`January`, `February`, `March`];
document
.writeln(`0>`+myArray[0]+`<BR>`);                  // Will output: 0>January
document
.writeln(`1>`+myArray[1]+`<BR>`);                  // Will output: 1>February
document
.writeln(`2>`+myArray[2]+`<BR>`);                  // Will output: 2>March

You can inizialize your array with data after an empty array has been created…

var myArray = [];
myArray
[0] = `January`;
myArray
[1] = `February`;
myArray
[2] = `March`;
document
.writeln(`0>`+myArray[0]+`<BR>`);                  // Will output: 0>January
document
.writeln(`1>`+myArray[1]+`<BR>`);                  // Will output: 1>February
document
.writeln(`2>`+myArray[2]+`<BR>`);                  // Will output: 2>March

If you skip an element, the “blank” Array elements will be of type “undefined”

var myArray = [];
myArray
[0] = `January`;
myArray
[1] = `February`;
myArray
[5] = `March`;
document
.writeln(`0>`+myArray[0]+`<BR>`);                  // Will output: 0>January
document
.writeln(`1>`+myArray[1]+`<BR>`);                  // Will output: 1>February
document
.writeln(`2>`+myArray[2]+`<BR>`);                  // Will output: 2>undefined
document
.writeln(`3>`+myArray[3]+`<BR>`);                  // Will output: 3>undefined
document
.writeln(`4>`+myArray[4]+`<BR>`);                  // Will output: 4>undefined
document
.writeln(`5>`+myArray[5]+`<BR>`);                  // Will output: 5>March

Storing Data In An Array

An array can store anything you can assign to a variable: booleans, numbers, strings, functions, objects, other Arrays, even regular expressions…

var myArray = [ 3, `hello!`, function() {return 5}, {`color`:`blue`, `budget`:25}, /[ell]/i ];
document
.writeln(`0>`+myArray[0]+`<BR>`);                  // Will output: 0>3
document
.writeln(`1>`+myArray[1]+`<BR>`);                  // Will output: 1>hello!
document
.writeln(`2>`+myArray[2]()+`<BR>`);                // Will output: 2>5
document
.writeln(`3>`+myArray[3].color+`<BR>`);            // Will output: 3>blue
document
.writeln(`3>`+myArray[3].budget+`<BR>`);           // Will output: 3>25
document
.writeln(`4>`+myArray[4].test(myArray[1])+`<BR>`); // Will output: 4>true

Multi-Dimensional Arrays

Since an Array can store other Arrays you can get the benefit of multi-dimension arrays.

var x=[0,1,2,3,4,5];
var y=[x];

In the above example we created an array named “x” and assigned it as the first element in the array “y”. If we ask for the value of y[0] it will return the contents of “x” as a string because we didn`t specify an index.

var x=[0,1,2,3,4,5];
var y=[x];
document
.writeln(y[0]); // Will output: 0,1,2,3,4,5

If we wanted the third index we`d access it this way…

var x=[0,1,2,3,4,5];
var y=[x];
document
.writeln(y[0][3]); // Will output: 2

There`s no defined limit to how many Arrays you can nest in this manner. For instance …

document.writeln(bigArray[5][8][12][1])

…would indicate bigArray`s 5th index held an array, who`s 8th index held an array, who`s 12th index held an array, who`s first index contains the data we want.

Javascript Arrays Are Passed By Reference

Arrays are passed to functions by reference, or as a pointer to the original. This means anything you do to the Array inside the function affects the original.

var myArray = [ `zero`, `one`, `two`, `three`, `four`, `five` ];

document
.writeln(myArray[1]); // Will output: one

function passedByReference(refArray) {
   refArray
[1] = `changed`;
}

passedByReference
(myArray);

document
.writeln(myArray[1]); // Will output: changed

Javascript Arrays Are Assigned By Reference

Assigning an Array to a new variable creates a pointer to the original Array. For instance…

var myArray = [ `zero`, `one`, `two`, `three`, `four`, `five` ];
var newArray= myArray;

newArray
[1] = `changed`;

document
.writeln(myArray[1]); // Will output: changed

Passing Arrays As Values

To pass an Array by value instead of by reference, use the Array.slice() method.

var myArray = [ `zero`, `one`, `two`, `three`, `four`, `five` ];
var newArray= myArray.slice();

newArray
[1] = `changed`;

document
.writeln(myArray[1]); // Will output: one

function passedByReference(refArray) {
   refArray
[1] = `changed`;
}

passedByReference
(myArray.slice());
document
.writeln(myArray[1]); // Will output: one

Array.length

Every Array has a “length” property. This always contains the number of elements in the array. Since Arrays always start at zero, the length property is convenient for loops since it will always be one greater than the actual index. For instance if the Array has 10 elements then the indexes will be 0-9, so as long as our counter is less than the Array.length we`ll cover the entire Array…

for (var i=0; i<myArray.length; i++) {}

Going back to our “undefined” example above. Even though 3 of the Array items are “undefined” the length property will still count them because it`s always one higher than the highest accessable index value.

var myArray = [];
myArray
[0] = `January`;
myArray
[1] = `February`;
myArray
[5] = `March`;
document
.writeln(`0>`+myArray[0]+`<BR>`);          // Will output: 0>January
document
.writeln(`1>`+myArray[1]+`<BR>`);          // Will output: 1>February
document
.writeln(`2>`+myArray[2]+`<BR>`);          // Will output: 2>undefined
document
.writeln(`3>`+myArray[3]+`<BR>`);          // Will output: 3>undefined
document
.writeln(`4>`+myArray[4]+`<BR>`);          // Will output: 4>undefined
document
.writeln(`5>`+myArray[5]+`<BR>`);          // Will output: 5>March
document
.writeln(`Array Length: `+myArray.length); // Will output: Array Length: 6

Array.length is NOT a read-only value, you can set it as you wish. If you have 100 elements in an array and set the length to 50, Javascript will truncate the last 50 elements from the array (effectively deleting them). If you have 10 elements in an array and set Array.length to 100 then the length of the array will be expanded to 100, creating 90 undefined elements after the original 10 items.

Javascript Does Not Support Associative Arrays

An associative array is an array which uses a string instead of a number as an index.

var normalArray    = [];
    normalArray
[1] = `This is an enumerated array`;

    alert
(normalArray[1]);   // outputs: This is an enumerated array

var associativeArray           = [];
    associativeArray
[`person`] = `John Smith`;

    alert
(associativeArray[`person`]); // outputs: John Smith    

Javascript does not have, and does not support Associative Arrays. However… All arrays in Javascript are objects and Javascript`s object syntax gives a basic emulation of an associative Array. For this reason the example code above will actually work. Be warned that this is not a real array and it has real pitfals if you try to use it. The `person` element in the example becomes part of the Array object`s properties and methods, just like .length, .sort(), .splice(), and all the other built-in properties and methods.

You can loop through an object`s properties with the following loop…

var associativeArray = [];
associativeArray
["one"] = "First";
associativeArray
["two"] = "Second";
associativeArray
["three"] = "Third";
for (i in associativeArray) {
   document
.writeln(i+`:`+associativeArray[i]+`, `);
   
// outputs: one:First, two:Second, three:Third
};

In the above example, associativeArray.length will be zero because we didn`t actually put anything into the Array, we put it into associativeArray`s object. “associativeArray[0]” will be undefined.

The loop in the above example will also pick up any methods, properties, and prototypes which have been added to the array and not just your data. A lot of problems people have with the Prototype library is that their “associative arrays” break because Prototype adds a few useful Prototype functions to the Array object and “for i in x” loops pick up those additional methods. That`s the pitfal of using Array/objects as a poor man`s associative array.

As a final example, the previous code will “work” regardless of whether you define associativeArray as an Array ([]), an Object({}), a Regular Expression (//), String(""), or any other Javascript object.

The bottom line is -- don`t try to use associative arrays, code for what they are -- object properties, not Arrays.

Array Methods Reference

Since Javascript Arrays are modified objects, each and every Array you create has a few core methods. What`s really interesting is that some of these methods implement basic data structures you`d normally have to write yourself such as stacks (push, pop) and queues (shift, unshift).

MethodIE VersionMozilla VersionNotes
concat4.04.0Joins multiple Arrays
every*FF 1.5Calls a function for every element of the array until false is returned.
filter*FF 1.5Creates an array with each element which evaluates true in the function provided.
forEach*FF 1.5Executes a specified function on each element of an Array
join3.03.0Joins all the Array elements together into a string.
indexOf*FF 1.5Searches the Array for specific elements.
lastIndexOf*FF 1.5Returns the last item in the Array which matches the search critera.
map*FF 1.5Creates a new array with the result of calling the specified function on each element of the Array.
pop5.54.0Returns the last item in the Array and removes it from the Array.
push5.54.0Adds the item to the end of the Array.
reverse3.03.0Reverses the Array so the last item becomes the first and vice-versa.
shift5.54.0Returns the first item in the Array and removes it from the Array.
slice4.04.0Returns a new array from the specified index and length.
some*FF 1.5Passes each element through the supplied function until “true” is returned.
sort3.03.0Sorts the array alphabetically or by the supplied function.
splice5.54.0Deletes the specified index(es) from the Array.
toSource---FF 1.5Returns the “source code” of the array.
toString3.03.0Returns the Array as a string.
unshift5.54.0Inserts the item(s) to the beginning of the Array.
valueOf3.03.0Like toString, returns the Array as a string.

* Prototype functions are available to make this method available to Internet Explorer and older browsers.

Array.concat(value1[value2[value...]])

The concat method appends the passed values to the end of the Array, passing back a NEW array containing the joined values. The values passed to the concat method can be anything you can assign to a variable in Javascript.

var myArray = [1,2,3];
var newArray= [4,5,6];
var seven = 7;
var eight = `eight`;
var nine = {`sky`:`blue`, `grass`:`green`};
var joinedArray=myArray.concat(newArray, seven, eight, nine);

document
.writeln(myArray);     // outputs: 1,2,3
document
.writeln(joinedArray); // outputs: 1,2,3,4,5,6,7,`eight`,[object Object]

Supported Since: Netscape 4.0, IE 4.0

Array.every(function)

The every method is a Firefox method which accepts a function as an argument. Every value of the array is passed to that function until the function returns false. If no elements return false then every will return true, if an element returned false then every will return false. It`s a convenient way to test an Array and see if every element is a number for instance.

This method will pass the current value, the current index, and a pointer to the array to your function. myfunction(curValue, curIndex, curArray)

var isNumeric = function(x) {
   
// returns true if x is numeric and false if it is not.
   
var RegExp = /^(-)?(\d*)(\.?)(\d*)$/;
   
return String(x).match(RegExp);
}
var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

document
.writeln(myArray.every(isNumeric));   // outputs: true

var myArray = [1,2,3,4,5,6,7,8,9,`ten`,11,12,13,14,15];

document
.writeln(myArray.every(isNumeric));   // outputs: false

This method can be prototyped to allow Internet Explorer and older browsers to use this method. Simply copy the following code into your Javascript toolbox and the .every() method will be available regardless of your browser version.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.every)
{
 
Array.prototype.every = function(fun /*, thisp*/)
 
{
   
var len = this.length;
   
if (typeof fun != "function")
     
throw new TypeError();

   
var thisp = arguments[1];
   
for (var i = 0; i < len; i++)
   
{
     
if (i in this &&
         
!fun.call(thisp, this[i], i, this))
       
return false;
   
}

   
return true;
 
};
}

Supported Since: Firefox 1.5, Internet Explorer: ---

Array.filter(function)

Filter creates a new Array of items which evaluate to true in the supplied function. In the Array.every() method, we tested if the entire Array was composed of Numbers. In Array.filter() we can extract all the numbers, creating a new Array in the process.

This method will pass the current value, the current index, and a pointer to the array to your function. myfunction(curValue, curIndex, curArray)

Here we pass the array through the same function as .every() -- isNumeric -- and if the element is a number it`s placed in the new “oddArray” Array.

var isNumeric = function(x) {
   
// returns true if x is numeric and false if it is not.
   
var RegExp = /^(-)?(\d*)(\.?)(\d*)$/;
   
return String(x).match(RegExp);
}
var myArray = [1,`two`,3,`four`,5,`six`,7,`eight`,9,`ten`];
var oddArray=myArray.filter(isNumeric);

document
.writeln(oddArray);   // outputs: 1,3,5,7,9

This method can be prototyped to allow Internet Explorer and older browsers to use this method. Simply copy the following code into your Javascript toolbox and the .filter() method will be available regardless of your browser version.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
 
Array.prototype.filter = function(fun /*, thisp*/)
 
{
   
var len = this.length;
   
if (typeof fun != "function")
     
throw new TypeError();

   
var res = new Array();
   
var thisp = arguments[1];
   
for (var i = 0; i < len; i++)
   
{
     
if (i in this)
     
{
       
var val = this[i]; // in case fun mutates this
       
if (fun.call(thisp, val, i, this))
          res
.push(val);
     
}
   
}

   
return res;
 
};
}

Supported Since: Firefox 1.5, Internet Explorer: ---

Array.forEach(function)

This is an odd little method. All it does is pass each element of the Array to the passed function. It ignores any results from the function and it returns nothing itself. It will pass all the Array contents through the function of your choice but the Array itself will not be affected and it will return nothing by itself.

This method will pass the current value, the current index, and a pointer to the array to your function. myfunction(curValue, curIndex, curArray)

var printArray = function (x, idx) {
   document
.writeln(`[`+idx+`] = `+x);
}

var myArray = [1,`two`,3,`four`,5];

myArray
.forEach(printArray); // outputs: [0] = 1 [1] = two [2] = 3 [3] = four [4] = 5

This method can be prototyped to allow Internet Explorer and older browsers to use this method. Simply copy the following code into your Javascript toolbox and the .forEach() method will be available regardless of your browser version.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.forEach)
{
 
Array.prototype.forEach = function(fun /*, thisp*/)
 
{
   
var len = this.length;
   
if (typeof fun != "function")
     
throw new TypeError();

   
var thisp = arguments[1];
   
for (var i = 0; i < len; i++)
   
{
     
if (i in this)
        fun
.call(thisp


-------------------------------------------------
上一篇:The Complete Javascript Strings Reference 下一篇:Functional Javascript



  
Are you Bot? How you know that?ofcz no.