数组

在 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%
}

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

dftg