Understanding Arrays within Arrays

Discussion in 'Javascript' started by MG, Apr 16, 2010.

  1. MG

    MG Guest

    I am learning javascript from a book.

    The example below is aimed at demonstrating drop down select menus. The
    alerts (commented out) were added by me.

    The example uses arrays within arrays, but doesn't explain them at all well.
    So I have some questions:

    What syntax would return Australia, France, Japan, New Zealand ?

    Why does cities[1][1] not work, but cities['France'][1] does?

    Any other useful help with arrays within arrays would be appreciated.

    Thanks
    MG



    =====================

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Related Select Test</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
    <script type="text/javascript">
    <!--
    // Create an array to hold the cities for each country
    var cities = new Array(4);
    cities["Australia"] =
    ["Sydney", "Melbourne", "Canberra", "Perth", "Brisbane"];
    cities["France"] =
    ["Paris", "Lyons", "Nice", "Dijon"];
    cities["Japan"] = ["Tokyo", "Kyoto", "Osaka", "Nara"];
    cities["New Zealand"] =
    ["Auckland", "Wellington", "Christchurch", "Dunedin", "Queenstown"];

    //alert(cities); does not work
    //alert(cities[1]); undefined
    //alert(cities[1][1]); does not work
    //alert(cities['France']); works
    //alert(cities['France'][1]); works


    function removeOptions(optionMenu)
    {
    for (var i=0; i < optionMenu.options.length; i++)
    optionMenu.options = null;
    }
    function addOptions(optionList, optionMenu)
    {
    removeOptions(optionMenu); // clear out the options
    for (var i=0; i < optionList.length; i++)
    optionMenu = new Option(optionList, optionList);
    }
    //-->
    </script>
    </head>
    <body>
    <h2>Vacation Chooser</h2>
    <form name="testform" id="testform" action="#" method="get">
    Country:
    <select name="country" id="country"
    onchange="addOptions(cities[this.options[this.selectedIndex].text],document.testform.city);">
    <option selected="selected">Australia</option>
    <option>France</option>
    <option>Japan</option>
    <option>New Zealand</option>
    </select>
    City:
    <select name="city" id="city">
    <option>Sydney</option>
    <option>Melbourne</option>
    <option>Canberra</option>
    <option>Perth</option>
    <option>Brisbane</option>
    </select>
    </form>
    </body>
    </html>
    MG, Apr 16, 2010
    #1
    1. Advertising

  2. On Fri, 16 Apr 2010 20:03:21 +0200, MG wrote:

    > I am learning javascript from a book.


    Good idea. Wish there any books that could be wholeheartedly recommended.

    >
    > The example below is aimed at demonstrating drop down select menus. The
    > alerts (commented out) were added by me.
    >
    > The example uses arrays within arrays, but doesn't explain them at all
    > well. So I have some questions:


    Actually ... it doesn't.

    This has been a reoccurping topic here on c.l.js I almost think we need
    a new FAQ entry. I'll even provide the basis.

    Javascript (or ECMAScript to be precise) has Objects. An object can hold
    key/value pairs, like this:

    var capitals = {
    "France":"Paris",
    "USA":"Washington DC."
    };

    alert(capitals.France); // Paris
    alert(capitals['France']; // Paris

    The doted notation has some limits on what key values may be used, the
    bracketed method has more flexibility.

    Arrays, on the other hand, use NUMERIC keys.

    var christmasList = [
    "My Front Teeth",
    "Five calling birds"
    ];

    alert(christmasList[1]);

    The confusion comes from this ...

    In Javascript arrays inherit from objects. EVERYTHING you can do with an
    object you can do with an array. Arrays are objects. But -- when you
    use a non-numeric key, you loose all of the array special features for
    that element.

    var a = ["Zero", "One", "Two"];
    for (var i = 1; i < a.length; i++) {
    alert(a);
    }

    a['hopeless'] = "You'll never see me in an array loop";

    So the short of it is.. if you want numeric keys, use an array. If you
    want string keys, use an object.


    >
    > What syntax would return Australia, France, Japan, New Zealand ?
    >
    > Why does cities[1][1] not work, but cities['France'][1] does?
    >
    > Any other useful help with arrays within arrays would be appreciated.
    >
    > Thanks
    > MG
    >
    >
    >
    > =====================
    >
    > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html
    > xmlns="http://www.w3.org/1999/xhtml"> <head>
    > <title>Related Select Test</title>
    > <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"
    > /> <script type="text/javascript">
    > <!--
    > // Create an array to hold the cities for each country var cities = new
    > Array(4);
    > cities["Australia"] =
    > ["Sydney", "Melbourne", "Canberra", "Perth", "Brisbane"];
    > cities["France"] =
    > ["Paris", "Lyons", "Nice", "Dijon"];
    > cities["Japan"] = ["Tokyo", "Kyoto", "Osaka", "Nara"]; cities["New
    > Zealand"] =
    > ["Auckland", "Wellington", "Christchurch", "Dunedin", "Queenstown"];
    >
    > //alert(cities); does not work
    > //alert(cities[1]); undefined
    > //alert(cities[1][1]); does not work //alert(cities['France']); works
    > //alert(cities['France'][1]); works
    >
    >
    > function removeOptions(optionMenu)
    > {
    > for (var i=0; i < optionMenu.options.length; i++) optionMenu.options
    > = null;
    > }
    > function addOptions(optionList, optionMenu) {
    > removeOptions(optionMenu); // clear out the options for (var i=0; i <
    > optionList.length; i++) optionMenu = new Option(optionList,
    > optionList); }
    > //-->
    > </script>
    > </head>
    > <body>
    > <h2>Vacation Chooser</h2>
    > <form name="testform" id="testform" action="#" method="get"> Country:
    > <select name="country" id="country"
    > onchange="addOptions(cities[this.options

    [this.selectedIndex].text],document.testform.city);">
    > <option selected="selected">Australia</option> <option>France</option>
    > <option>Japan</option>
    > <option>New Zealand</option>
    > </select>
    > City:
    > <select name="city" id="city">
    > <option>Sydney</option>
    > <option>Melbourne</option>
    > <option>Canberra</option>
    > <option>Perth</option>
    > <option>Brisbane</option>
    > </select>
    > </form>
    > </body>
    > </html>
    Jeremy J Starcher, Apr 16, 2010
    #2
    1. Advertising

  3. MG

    MG Guest

    "Jeremy J Starcher" <> wrote in message
    news:0R1yn.71376$...
    > On Fri, 16 Apr 2010 20:03:21 +0200, MG wrote:
    >
    >> I am learning javascript from a book.

    >
    > Good idea. Wish there any books that could be wholeheartedly recommended.
    >
    >>
    >> The example below is aimed at demonstrating drop down select menus. The
    >> alerts (commented out) were added by me.
    >>
    >> The example uses arrays within arrays, but doesn't explain them at all
    >> well. So I have some questions:

    >
    > Actually ... it doesn't.


    I understand what you mean. In the example, I replaced this line:
    var cities = new Array(4);
    with this one:
    var cities = new Object();
    Everything works just the same.

    So the book is very misleading when it says "Create an array to hold the
    cities for each country"




    >
    > This has been a reoccurping topic here on c.l.js I almost think we need
    > a new FAQ entry. I'll even provide the basis.
    >
    > Javascript (or ECMAScript to be precise) has Objects. An object can hold
    > key/value pairs, like this:
    >
    > var capitals = {
    > "France":"Paris",
    > "USA":"Washington DC."
    > };
    >
    > alert(capitals.France); // Paris
    > alert(capitals['France']; // Paris
    >
    > The doted notation has some limits on what key values may be used, the
    > bracketed method has more flexibility.
    >
    > Arrays, on the other hand, use NUMERIC keys.
    >
    > var christmasList = [
    > "My Front Teeth",
    > "Five calling birds"
    > ];
    >
    > alert(christmasList[1]);
    >
    > The confusion comes from this ...
    >
    > In Javascript arrays inherit from objects. EVERYTHING you can do with an
    > object you can do with an array. Arrays are objects. But -- when you
    > use a non-numeric key, you loose all of the array special features for
    > that element.
    >
    > var a = ["Zero", "One", "Two"];
    > for (var i = 1; i < a.length; i++) {
    > alert(a);
    > }
    >
    > a['hopeless'] = "You'll never see me in an array loop";
    >
    > So the short of it is.. if you want numeric keys, use an array. If you
    > want string keys, use an object.
    >
    >
    >>
    >> What syntax would return Australia, France, Japan, New Zealand ?
    >>
    >> Why does cities[1][1] not work, but cities['France'][1] does?
    >>
    >> Any other useful help with arrays within arrays would be appreciated.
    >>
    >> Thanks
    >> MG
    >>
    >>
    >>
    >> =====================
    >>
    >> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    >> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html
    >> xmlns="http://www.w3.org/1999/xhtml"> <head>
    >> <title>Related Select Test</title>
    >> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"
    >> /> <script type="text/javascript">
    >> <!--
    >> // Create an array to hold the cities for each country var cities = new
    >> Array(4);
    >> cities["Australia"] =
    >> ["Sydney", "Melbourne", "Canberra", "Perth", "Brisbane"];
    >> cities["France"] =
    >> ["Paris", "Lyons", "Nice", "Dijon"];
    >> cities["Japan"] = ["Tokyo", "Kyoto", "Osaka", "Nara"]; cities["New
    >> Zealand"] =
    >> ["Auckland", "Wellington", "Christchurch", "Dunedin", "Queenstown"];
    >>
    >> //alert(cities); does not work
    >> //alert(cities[1]); undefined
    >> //alert(cities[1][1]); does not work //alert(cities['France']); works
    >> //alert(cities['France'][1]); works
    >>
    >>
    >> function removeOptions(optionMenu)
    >> {
    >> for (var i=0; i < optionMenu.options.length; i++) optionMenu.options
    >> = null;
    >> }
    >> function addOptions(optionList, optionMenu) {
    >> removeOptions(optionMenu); // clear out the options for (var i=0; i <
    >> optionList.length; i++) optionMenu = new Option(optionList,
    >> optionList); }
    >> //-->
    >> </script>
    >> </head>
    >> <body>
    >> <h2>Vacation Chooser</h2>
    >> <form name="testform" id="testform" action="#" method="get"> Country:
    >> <select name="country" id="country"
    >> onchange="addOptions(cities[this.options

    > [this.selectedIndex].text],document.testform.city);">
    >> <option selected="selected">Australia</option> <option>France</option>
    >> <option>Japan</option>
    >> <option>New Zealand</option>
    >> </select>
    >> City:
    >> <select name="city" id="city">
    >> <option>Sydney</option>
    >> <option>Melbourne</option>
    >> <option>Canberra</option>
    >> <option>Perth</option>
    >> <option>Brisbane</option>
    >> </select>
    >> </form>
    >> </body>
    >> </html>

    >
    MG, Apr 16, 2010
    #3
  4. On Fri, 16 Apr 2010 21:37:22 +0200, MG wrote:

    > "Jeremy J Starcher" <> wrote in message
    > news:0R1yn.71376$...
    >> On Fri, 16 Apr 2010 20:03:21 +0200, MG wrote:
    >>
    >>> I am learning javascript from a book.

    >>
    >> Good idea. Wish there any books that could be wholeheartedly
    >> recommended.
    >>
    >>
    >>> The example below is aimed at demonstrating drop down select menus.
    >>> The alerts (commented out) were added by me.
    >>>
    >>> The example uses arrays within arrays, but doesn't explain them at all
    >>> well. So I have some questions:

    >>
    >> Actually ... it doesn't.

    >
    > I understand what you mean. In the example, I replaced this line: var
    > cities = new Array(4);
    > with this one:
    > var cities = new Object();


    It is better style to write that as:
    var cities = {};

    In this case, it won't make any difference, but in this example:
    var array1 = new Array(5);
    var array2 = [5];

    do two, quite different things.
    array1.length === 5, with all elements being undefined.
    array2.length === 1 && array[0] === 5

    var array1 = new Array(5,6);
    var array2 = [5,6];

    do exactly the same thing. Avoid the confusion and use "[]" and "{}"
    syntax.


    > Everything works just the same.


    Exactly.
    > So the book is very misleading when it says "Create an array to hold the
    > cities for each country"


    Most books are misleading. In Javascript, that tends to be even more
    true than usual. Some authors know a language like PHP or PERL where
    arrays can have both string and numeric keys. They try it and it seems
    to work, so thats what they write.

    ((Sorry about not trimming my quote last time.))
    Jeremy J Starcher, Apr 16, 2010
    #4
  5. Jeremy J Starcher wrote:

    > This has been a reoccurping topic here on c.l.js I almost think we need
    > a new FAQ entry. I'll even provide the basis.


    It would be better if you wouldn't.

    > Javascript (or ECMAScript to be precise) has Objects. An object can hold
    > key/value pairs, like this:


    An object holds (attributed) name-value pairs that are called "properties".

    ,-[ES5, 4.2 Language Overview (non-normative)]
    |
    | An ECMAScript object is a collection of properties each with zero or more
    | attributes that determine how each property can be used [...].
    | Properties are containers that hold other objects, primitive values, or
    | functions.

    ,-[ES5, 4.3 Definitions (normative)]
    |
    | 4.3.26
    | property
    | association between a name and a value that is a part of an object.
    |
    | NOTE
    | Depending upon the form of the property the value may be represented
    | either directly as a data value (a primitive value, an object, or a
    | function object) or indirectly by a pair of accessor functions.

    > var capitals = {
    > "France":"Paris",
    > "USA":"Washington DC."
    > };
    >
    > alert(capitals.France); // Paris
    > alert(capitals['France']; // Paris
    >
    > The doted notation has some limits on what key values may be used, the
    > bracketed method has more flexibility.


    There are no keys, there are property names. Property names that are
    identifiers can be used with the dot _notation_; other names require the
    bracket notation.

    ,-[ES5, 11.2.1 Property Accessors]
    |
    | Properties are accessed by name, using either the dot notation:
    |
    | MemberExpression . IdentifierName
    | CallExpression . IdentifierName
    |
    | or the bracket notation:
    |
    | MemberExpression [ Expression ]
    | CallExpression [ Expression ]
    |
    | The dot notation is explained by the following syntactic conversion:
    |
    | MemberExpression . IdentifierName
    |
    | is identical in its behaviour to
    |
    | MemberExpression [ <identifier-name-string> ]
    |
    | and similarly
    |
    | CallExpression . IdentifierName
    |
    | is identical in its behaviour to
    |
    | CallExpression [ <identifier-name-string> ]
    |
    | where <identifier-name-string> is a string literal containing the same
    | sequence of characters after processing of Unicode escape sequences as
    | the IdentifierName.

    > Arrays, on the other hand, use NUMERIC keys.


    All property names are string values. Some property names are special with
    Arrays, though. (See below.)

    > var christmasList = [
    > "My Front Teeth",
    > "Five calling birds"
    > ];
    >
    > alert(christmasList[1]);


    window.alert(christmasList["1"]);

    is equivalent because property names are strings, and the bracket property
    accessor converts its parameter to a primitive string value before property
    access if necessary.

    > The confusion comes from this ...


    That you don't really know what you are talking about?

    > In Javascript arrays inherit from objects.


    There is no "Javascript":
    <http://PointedEars.de/es-matrix> (updated yesterday)

    In ECMAScript implementations like JavaScript or JScript, array
    functionality is encapsulated by objects, Array instances.

    > EVERYTHING you can do with an object you can do with an array.


    No. To begin with, there are some values that you cannot assign to the
    `length' property of Array instances because it is special, where there is
    no problem assigning them to the `length' property of Object instances.
    Most notably, though, you cannot inherit from Array.prototype and keep the
    behavior of Array instances.

    > Arrays are objects.


    Somewhat correct.

    > But -- when you use a non-numeric key, you loose all of the array special
    > features for that element.


    The proper spelling is _lose_, and that is only correct if you defined "non-
    numeric key" as the opposite of what is specified as special for properties
    of Array instances in the ECMAScript Language Specification (here quoted
    from Edition 5):

    | 15.4 Array Objects
    |
    | Array objects give special treatment to a certain class of property names.
    | A property name P (in the form of a String value) is an array index if and
    | only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
    | to 2^32−1. A property whose property name is an array index is also called
    | an element. Every Array object has a length property whose value is always
    | a nonnegative integer less than 2^32. The value of the length property is
    | numerically greater than the name of every property whose name is an array
    | index; whenever a property of an Array object is created or changed, other
    | properties are adjusted as necessary to maintain this invariant.
    | Specifically, whenever a property is added whose name is an array index,
    | the length property is changed, if necessary, to be one more than the
    | numeric value of that array index; and whenever the length property is
    | changed, every property whose name is an array index whose value is not
    | smaller than the new length is automatically deleted. This constraint
    | applies only to own properties of an Array object and is unaffected by
    | length or array index properties that may be inherited from its
    | prototypes.

    In short: "numeric keys" that are not representable as unsigned 32-bit
    integer values less than 2 to the power of 32 do not access array elements
    either.

    > var a = ["Zero", "One", "Two"];
    > for (var i = 1; i < a.length; i++) {
    > alert(a);
    > }


    That is a misleading example. The `for' loop should start at 0.

    > a['hopeless'] = "You'll never see me in an array loop";


    What is an "array loop"? Consider this:

    for (var i in a)
    {
    window.alert(a);
    }

    > So the short of it is.. if you want numeric keys, use an array. If you
    > want string keys, use an object.


    Rubbish. Good advice is that one should use an Array instance only when
    one needs the special properties and behavior of Array instances. That
    includes, but is not limited to, use of the `length' property.

    Please trim your quotes to the relevant minimum.


    PointedEars
    --
    var bugRiddenCrashPronePieceOfJunk = (
    navigator.userAgent.indexOf('MSIE 5') != -1
    && navigator.userAgent.indexOf('Mac') != -1
    ) // Plone, register_function.js:16
    Thomas 'PointedEars' Lahn, Apr 16, 2010
    #5
  6. Thomas 'PointedEars' Lahn wrote:

    > Jeremy J Starcher wrote:
    >> But -- when you use a non-numeric key, you loose all of the array special
    >> features for that element.

    >
    > The proper spelling is _lose_, and that is only correct if you defined
    > "non- numeric key" as the opposite of what is specified as special for
    > properties of Array instances in the ECMAScript Language Specification
    > (here quoted from Edition 5):
    >
    > | 15.4 Array Objects
    > |
    > | Array objects give special treatment to a certain class of property
    > | names. A property name P (in the form of a String value) is an array
    > | index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P)
    > | is not equal to 2^32−1. A property whose property name is an array index
    > | is also called an element. Every Array object has a length property
    > | whose value is always a nonnegative integer less than 2^32. The value of
    > | the length property is numerically greater than the name of every
    > | property whose name is an array index; whenever a property of an Array
    > | object is created or changed, other properties are adjusted as necessary
    > | to maintain this invariant. Specifically, whenever a property is added
    > | whose name is an array index, the length property is changed, if
    > | necessary, to be one more than the numeric value of that array index;
    > | and whenever the length property is changed, every property whose name
    > | is an array index whose value is not smaller than the new length is
    > | automatically deleted. This constraint applies only to own properties of
    > | an Array object and is unaffected by length or array index properties
    > | that may be inherited from its prototypes.
    >
    > In short: "numeric keys" that are not representable as unsigned 32-bit
    > integer values less than 2 to the power of 32


    .... minus 1 ...

    > do not access array elements either.


    (That is necessary because the element at index 2^32-1 would set the
    `length' property value to 2^32, which is forbidden.)


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
    Thomas 'PointedEars' Lahn, Apr 16, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. deancoo
    Replies:
    3
    Views:
    385
    Rolf Magnus
    Feb 14, 2005
  2. deancoo
    Replies:
    9
    Views:
    353
    Mark Van Peteghem
    Feb 14, 2005
  3. Jeff Newman
    Replies:
    5
    Views:
    438
    James Kanze
    Oct 30, 2008
  4. Abe
    Replies:
    2
    Views:
    159
  5. Nick Black

    matching arrays within arrays

    Nick Black, Jan 23, 2007, in forum: Ruby
    Replies:
    3
    Views:
    134
    Nick Black
    Jan 23, 2007
Loading...

Share This Page