# 数组

在 AutoHotkey 中, 有两种不同类型的事物与数组相关:

- 基于对象的数组
- 伪数组(不推荐使用)

注意: 下面的示例代码显示了导致相同最终结果的不同方法.

## 基于对象的数组

这样的数组可以是关联数组或简单数组. 关联数组使用 Map 函数创建, 而简单数组使用 Array 函数或方括号语法创建. 有关更多信息, 请参阅初学者向导(快速入门) 或对象页面.

以下示例展示了简单数组的用法:

    ; 创建数组后, 初始为空:
    MyArray := [] ; 或 MyArray := Array()

    ; 写入数据到数组:
    Loop Read A_WinDir "\system.ini" ; 此循环获取文件中的每行, 一次一行.
    {
        MyArray.Push(A_LoopReadLine) ; 添加此行到数组中.
    }

    ; 从数组中读取:
    ; Loop MyArray.Length   ; 较传统的方式.
    for index, element in MyArray ; 在大多数情况下建议使用枚举的方式.
    {
        ; 使用 "Loop", 索引必须是连续的数字
        ; 从 1 到数组中元素的个数(或者必须在循环中进行计算).
        ; MsgBox "Element number " . A_Index . " is " . MyArray[A_Index]

        ; 使用 "for", 同时提供了索引(或"键") 及与它关联的值
        ; 并且索引可以是您选择的*任何*值.
        MsgBox "Element number " . index . " is " . element
    }

这只显示了简单数组提供的功能的一小部分(或关联数组(也称为 Map 对象) 提供的功能的一小部分). 可以设置, 获取, 插入, 移除和枚举项目. 除了数字, 字符串和任何类型的和对象都可以用作键. 对象可以作为值存储到其他对象中, 并且可以作为函数参数或返回值传递. 对象还可以使用新特性进行扩展.

尽管 Push() 和枚举器有它们的用途, 不过一些用户可能会发现使用更为传统的方法更容易(注释掉的行对应使用下面描述伪数组):

    ; 每个数组在使用前必须进行初始化:
    MyMap := Map()

    ; MyMap%j% := A_LoopField
    MyMap[j] := A_LoopField

    ; MyMap%j%_%k% := A_LoopReadLine
    MyMap[j] := Map()
    MyMap[j][k] := A_LoopReadLine

    MyMapLength := 0
    Loop Read A_WinDir "\system.ini"
    {
        MyMapLength += 1
        ; MyMap%MyMapLength% := A_LoopReadLine
        MyMap[MyMapLength] := A_LoopReadLine
    }

    Loop MyMapLength
    {
        ; element := MyMap%A_Index%
        element := MyMap[A_Index]
        ; MsgBox "Element number " . A_Index . " is " . MyMap%A_Index%
        MsgBox "Element number " . A_Index . " is " . MyMap[A_Index]
    }

为了方便起见, MyMapLength 保留为变量, 但可以使用 `MyMap.Length := n` 存储在数组本身中, 也可以将其删除并使用 `MyMap.Count` 代替.

## 伪数组

注意: 如果可能, 请总是使用上面提到的基于对象的数组. 它在几乎每个方面都优于伪数组: 它具有节省空间, 更灵活, 更清晰, 与许多其他编程语言相似的特点.

伪数组主要是概念性的: 每个数组实际上只是按顺序编号的变量或函数的集合, 每个变量或函数都被视为数组的 element(元素). AutoHotkey 不会以任何方式将这些元素链接在一起.

任何接受 OutputVar 的函数或为变量赋值都可以用来创建数组. 最简单的示例是赋值运算符(:=), 如下所示:

    Array%j% := A_LoopField

通过在索引之间使用所选的分隔符, 可以实现多维数组. 例如:

    Array%j%_%k% := A_LoopReadLine

下面的示例演示了如何创建和访问数组, 这里是从文本文件中检索一系列名称:

    ; 写入到数组:
    ArrayCount := 0
    Loop Read A_WinDir "\system.ini"   ; 此循环获取文件中的每行, 一次一行.
    {
        ArrayCount += 1  ; 记录数组中的项目数.
        Array%ArrayCount% := A_LoopReadLine  ; 把此行保存到数组中的下一个元素.
    }

    ; 从数组中读取:
    Loop ArrayCount
    {
        ; 下一行使用 := 运算符获取数组元素:
        element := Array%A_Index%  ; A_Index 是内置变量.
        ; 可选地, 您可以执行以下操作, 因为默认情况下所有函数都接受表达式 by default:
        MsgBox "Element number " . A_Index . " is " . Array%A_Index%
    }

与数组有关的一个概念是使用 NumPut 和 NumGet 以二进制格式存储/检索数字集合. 在对性能和/或内存占用有要求的情况下, 这可能会有所帮助.

dftg