[This is preliminary documentation and subject to change]

# Working with Collections

Most of the ASP built-in objects provide collections. Collections are data structures similar to arrays that store strings, numbers, objects and other values. Unlike arrays, collections expand and contract automatically as items are retrieved or stored. The position of an item will also move as the collection is modified. You can access an item in a collection by its unique string key, by its index (position) in the collection, or by iterating through all the items in the collection.

## Accessing an Item by Name or Index

You can access a specific item in a collection by referencing its unique string key, or name. For example, the Contents collection holds any variables stored in the Session object. It can also hold any objects instantiated by calling Server.CreateObject. Suppose you have stored the following user information in the Session object:

    <%
      Session.Contents("FirstName") = "Meng"
      Session.Contents("LastName") = "Phua"
      Session.Contents("Age") = 29
    %>

You can access an item by using the string key you associated with the item when you stored it in the collection. For example, the following expression returns the string "Meng":

    <%= Session.Contents("FirstName") %>

You could also access an item by using the index, or number, associated with an item. For example, the following expression retrieves the information stored in the second position of the Session object and returns "Phua":

    <%= Session.Contents(2) %>

ASP collections are numbered starting with 1. The index associated with an item might change as items are added to or removed from the collection. You should not depend on an item's index remaining the same. Indexed access is generally used to iterate through a collection, as described in the following topics, or to access an item in a read-only collection.

You can also use a shorthand notation to access items by name. ASP searches the collections associated with an object in a particular order. If an item with a particular name appears only once in an object's collections, you can eliminate the collection name (although doing so may affect performance):

    <%= Session("FirstName") %>

Eliminating the collection name is generally safe when you are accessing items stored in the Application or Session object. For the Request object, however, it is safer to specify the collection name because the collections could easily contain items with duplicate names.

## Iterating through a Collection

You can iterate through all the items in a collection to see what is stored in the collection or to modify the items. You must supply the collection name when you iterate through a collection. For example, you can use the VBScript For...Each statement to access the items you stored in the Session object:

    <%
      'Declare a counter variable.
      Dim strItem

      'For each item in the collection, display its value.
      For Each strItem In Session.Contents
        Response.Write Session.Contents(strItem) & "<BR>"
      Next
    %>

You can also iterate through a collection by using the VBScript For...Next statement. For example, to list the three items stored in Session by the previous example, use the following statements:

    <%
      'Declare a counter variable.
      Dim intItem

      'Repeat the loop until the value of counter is equal to 3.
      For intItem = 1 To 3
        Response.Write Session.Contents(intItem) & "<BR>"
      Next
    %>

Because you do not usually know how many items are stored in a collection, ASP supports the Count property for a collection, which returns the number of items in the collection. You use the Count property to specify the end value of the counter.

    <%
      'Declare a counter variable.
      Dim lngItem, lngCount

      lngCount = Session.Contents.Count

      'Repeat this loop until the counter equals the number of items
      'in the collection.
      For lngItem = 1 To lngCount
         Response.Write Session.Contents(lngItem) & "<BR>"
      Next
    %>

In JScript, you use the for statement to loop through a collection. For greater efficiency when using the Count property with a JScript for statement, you should assign the value of Count to a local variable and use that variable to set the end value of the counter. That way, the script engine does not have to look up the value of Count each time through the loop. The following example demonstrates this technique:

    <%
      var intItem, intNumItems;

      intNumItems = Session.Contents.Count;

      for (intItem = 1; intItem <= intNumItems; intItem++)
      {
        Response.Write(Session.Contents(intItem) + "<BR>")
      }
    %>

Microsoft JScript supports an Enumerator object that you can also use to iterate through an ASP collection. The atEnd method indicates whether there are any more items in the collection. The moveNext method moves to the next item in the collection.

    <%
      Session.Contents("Name") = "Suki White"
      Session.Contents("Department") = "Hardware"
            .
            .
            .
      //Create an Enumerator object.
      var myCollection = new Enumerator(Session.Contents);

      //Iterate through the collection and display each item.
      while (!myCollection.atEnd())
      {
        var x  = myCollection.item();
        Response.Write(Session.Contents(x) + "<BR>");
        myCollection.moveNext();
      }
    %>

## Iterating through a Collection with Subkeys

Scripts might embed several related values in a single cookie to reduce the number of cookies passed between the browser and the Web server. The Cookies collection of the Request and Response objects can thus hold multiple values in a single item. These subitems, or subkeys, can be accessed individually. Subkeys are supported only by the Request.Cookies and Response.Cookies collections. Request.Cookies supports only read operations; Response.Cookies supports only write operations.

The following creates a regular cookie and a cookie with a subkeys:

    <%
      'Send a cookie to the browser.
      Response.Cookies("Fruit") = "Pineapple"

      'Send a cookie with subkeys to browser.
      Response.Cookies("Mammals")("Elephant") = "African"
      Response.Cookies("Mammals")("Dolphin") = "Bottlenosed"
    %>

The cookie text in the HTTP response sent to the browser would appear as the following:

    HTTP_COOKIE= Mammals=ELEPHANT=African&DOLPHIN=Bottlenosed; Fruit=Pineapple;

You can also enumerate all the cookies in the Request.Cookies collection and all the subkeys in a cookie. However, iterating through subkeys on a cookie that does not have subkeys will not produce an item. You can avoid this situation by first checking to see whether a cookie has subkeys by using the HasKeys attribute of the Cookies collection. This technique is demonstrated in the following example.

    <%
       'Declare counter variables.
       Dim Cookie, Subkey

       'Display the entire cookie collection.
       For Each Cookie In Request.Cookies
         Response.Write Cookie
         If Request.Cookies(Cookie).HasKeys Then
           Response.Write "<BR>"
           'Display the subkeys.
           For Each Subkey In Request.Cookies(Cookie)
             Response.Write " ->" & Subkey & " = " & Request.Cookies(Cookie)(Subkey) & "<BR>"
           Next
         Else
           Response.Write " = " & Request.Cookies(Cookie) & "<BR>"
         End If
       Next
    %>

This script would return the following results:

    Mammals
    ->ELEPHANT = African
    ->DOLPHIN = Bottlenosed
    Fruit = Pineapple

## The Case of the Key Name

The Cookies, Request, Response, and ClientCertificate collections can reference the same, unique string key name. For example, the following statements reference the same key name, User, but return different values for each collection:

    strUserID = Request.Cookies("User")
    strUserName = Request.QueryString("User")

The case of the key name is set by the first collection to assign a value to the key. Examine the following script:

    <%
      'Retrieve a value from QueryString collection using the UserID key.
      strUser = Request.QueryString("UserID")

      'Send a cookie to the browser, but reference the key, UserId, which has a different spelling.
      Response.Cookies("UserId")= "1111-2222"
      Response.Cookies("UserId").Expires="December 31, 2000"
    %>

Although it may appear that key name UserId was assigned to the cookie, in actuality, the key name UserID (which is capitalized differently) was assigned to the cookie. The QueryString collection was first to define the case of this key.

Because references to collection values are independent of the case of the key name, this behavior will not affect your scripts unless your application uses case sensitive processing of key names.

## Iterating through a Collection of Objects

The Session and Application collections can hold either scalar variables or object instances. The Contents collection holds both scalar variables and object instances created by calling Server.CreateObject. The StaticObjects collection holds objects created by using the HTML <OBJECT> tag within the scope of the Session object. For more information about instantiating objects in this manner, see Setting Object Scope.

When you iterate through a collection that contains objects, you can either access the object's Session or Application state information or access the object's methods or properties. For example, suppose your application uses several objects to create a user account, and each object has an initialization method. You could iterate through the StaticObjects collection to retrieve object properties:

    <%
      For Each Object in Session.StaticObjects
        Response.Write Object & ": " & Session.StaticObjects(Object)
      Next
    %>

## What's Different About ASP Collections?

Although the ASP collections described in this topic are similar to the Visual Basic Collection object, there are some differences. The ASP collections support the Count property and the Item, Remove, and RemoveAll methods. They do not support the Add method.

© 1997-2001 Microsoft Corporation. All rights reserved.