# 使用集合

多数 ASP 内置对象都提供集合。“集合”是类似于数组的数据结构，可存储字符串、数值、对象和其他值。与数组不同的是，集合可以根据所获得或存储的项目自动伸缩。随着集合发生变化，项目的位置也将变动。要访问集合中的项目，可以通过项目唯一的字符串关键字、项目在集合中的索引（位置）或迭代集合中的所有项目来实现。

## 根据名称或索引访问项目

可以通过引用唯一字符串关键字或名称来访问集合中的指定项目。例如，Contents 集合载有 Session 对象中存储的所有变量。它还可以载有通过调用 Server.CreateObject 而进行实例化的对象。假设您在 Session 对象中储存了下列用户信息：

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

可以使用存入集合时与项目予以关联的字符串关键字访问此项目。例如，下列表达式返回字符串“Meng”：

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

还可以使用与项目关联的索引或数字访问项目。例如，下列表达式获得存储在 Session 对象第二部分中的信息并返回“Phua”。

    <%= Session.Contents(2) %>

ASP 集合的标号从 1 开始。当在集合中添加或删除项目时，与项目相关联的索引也将更改。不应将项目索引视为是一成不变的。索引访问通常用于迭代一个集合，如下列主题中所述，或访问只读集合中的项目。

还可以使用速记符根据名称访问项目。ASP 可搜索与特定顺序的对象相关联的集合。如果具有特定名称的项目仅在对象集合中出现一次，则可以删除集合名称（尽管这样做会影响性能）：

    <%= Session("FirstName") %>

当访问存储在 Application 或 Session 对象中的项目时，删除集合名称一般来说是安全的。但对于 Request 对象，指定集合名称则更为安全。因为集合很容易包含具有重复名称的项目。

## 迭代集合

可以迭代集合中的所有项目，查看集合中存储的信息或更改项目。进行集合迭代时必须提供集合名称。例如，可以使用 VBScript 中的 For...Each 语句访问存储在 Session 对象中的项目。

    <%
      '声明计数器变量。
      Dim strItem

      '显示集合中每个项目的值。
      For Each strItem In Session.Contents
        Response.Write Session.Contents(strItem) & "<BR>"
      Next
    %>

还可以使用 VBScript 中的 For...Next 语句迭代集合。例如，列出通过上例存储在 Session 中的三个项目，可以使用下列语句：

    <%
      '声明计数器变量。
      Dim intItem

      '重复循环，直到计数器的值达到 3。
      For intItem = 1 To 3
        Response.Write Session.Contents(intItem) & "<BR>"
      Next
    %>

由于通常不知道集合中所存储的项目数，ASP 支持集合的 Count 属性，此属性返回集合中的项目个数。可以使用 Count 属性指定计数器的最大值。

    <%
      '声明计数器变量。
      Dim lngItem, lngCount

      lngCount = Session.Contents.Count

      '重复循环，直到计数器的值等于
      '集合中的项目个数。
      For lngItem = 1 To lngCount
         Response.Write Session.Contents(lngItem) & "<BR>"
      Next
    %>

在 JScript 中，可以使用 for 语句可迭代集合。要提高在 JScript 的 for 语句中使用 Count 属性的效率，应将 Count 值分配给本地变量，并用此变量来设置计数器的最大值。这样，脚本引擎就不必每次循环都去查找 Count 值。以下示例说明了这一技巧：

    <%
      var intItem, intNumItems;

      intNumItems = Session.Contents.Count;

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

Microsoft JScript 支持 Enumerator 对象，也可使用它来迭代 ASP 集合。atEnd 方法标明集合中是否还存在其他项目。moveNext 方法用于移动到下一个集合项目。

    <%
      Session.Contents("Name") = "Suki White"
      Session.Contents("Department") = "Hardware"
    		.
    		.
    		.
      //创建枚举器对象。
      var mycollection = new Enumerator(Session.Contents);

      //在集合中迭代并显示每个项目。
      while (!mycollection.atEnd())
      {
        var x  = myCollection.item();
        Response.Write(Session.Contents(x) + "<BR>");
        myCollection.moveNext();
      }
    %>

## 使用子关键字迭代整个集合

脚本可在单个 cookie 中嵌入多个关联值，以便减少在浏览器和 Web 服务器之间传递的 cookie 数目。Request 和 Response 对象的 Cookies 集合可在单个项目中载有多个值。这些子项目或子关键字可单独使用。只有 Request.Cookies 和 Response.Cookies 集合支持子关键字。Request.Cookies 仅支持读操作，Response.Cookies 仅支持写操作。

下面将创建一个普通 cookie 和一个带子关键字的 cookie：

    <%
      '将 cookie 发送到浏览器。
      Response.Cookies("Fruit") = "Pineapple"

      '用子关键字将 cookie 发送到浏览器。
      Response.Cookies("Mammals")("Elephant") = "African"
      Response.Cookies("Mammals")("Dolphin") = "Bottlenosed"
    %>

发送到浏览器的 HTTP 响应中的 cookie 文本显示如下：

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

可以列举出 Request.Cookies 集合中的所有 cookies 以及 cookies 中的所有子关键字。不过，对不存在子关键字的 cookie 迭代子关键字将无法生成项目。要避免出现这种情况，请先检查 cookie 的子关键字是否是使用 Cookies 集合的 HasKeys 属性得到的。这一技巧将在以下示例中加以说明。

    <%
       '声明计数器变量。
       Dim Cookie, Subkey

       '显示整个 cookie 集合。
       For Each Cookie In Request.Cookies
         Response.Write Cookie
         If Request.Cookies(Cookie).HasKeys Then
           Response.Write "<BR>"
           '显示子关键字。
           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
    %>

此脚本将返回下列结果：

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

## 关键字名称的大小写

Cookies、Request、Response 和 ClientCertificate 集合可引用相同的唯一字符串关键字名称。例如，下列语句引用了同一关键字名称 User，但对于每一个集合却返回了不同的值：

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

关键字名称的大小写由第一个集合将值赋给关键字时设定。请查看下列脚本：

    <%
      '使用 UserID 关键字检索 QueryString 集合中的值。
      strUser = Request.QueryString("UserID")

      '将 cookie 发送到浏览器，但引用关键字 UserId，该关键字使用不同的拼写。
      Response.Cookies("UserId")= "1111-2222"
      Response.Cookies("UserId").Expires="December 31, 2000"
    %>

尽管看上去好象将关键字名称 UserId 赋给了 cookie，但实际上，赋给 cookie 的是关键字名称 UserId（其大小写不同）。QueryString 集合首先定义了此关键字的大小写。

由于对集合值的引用与关键字名称的大小写无关，因此这一行为将不会影响脚本，除非应用程序对关键字名称使用了区分大小写的处理过程。

## 迭代对象的集合

Session 和 Application 集合既可使用标量变量也可使用对象实例。Contents 集合同时载有由调用 Server.CreateObject 而创建的标量变量和对象实例。StaticObjects 集合载有由 HTML 的 <OBJECT> 标记在 Session 对象的作用域之内创建的对象。关于用此方法实例化对象的详细信息，请参阅设置对象作用域。

迭代包含对象的集合时，既可访问对象的 Session 或 Application 状态信息，也可访问其方法或属性。例如，假设应用程序使用多个对象创建用户帐号，而每个对象都具有实例化方法。可以迭代 StaticObjects 集合以获取对象属性：

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

## ASP 集合有什么不同之处？

尽管本主题中说明的 ASP 集合与 Visual Basic 中的 Collection 对象十分类似，但它们仍有一些区别。ASP 集合支持 Count 属性以及 Item、Remove 和 RemoveAll 方法，但不支持 Add 方法。

© 1997-2001 Microsoft Corporation. 保留所有权利。