前邊我們講了變量丸相,打了一個(gè)形象的比喻,就是把變量比作吃飯的碗彼棍,量(值)就是飯灭忠。其實(shí)呢,數(shù)組跟變量是有直接關(guān)系的座硕,變量是數(shù)組的基礎(chǔ)弛作,變量的是碗的話,數(shù)組就好像是一個(gè)多功能的飯盒华匾,可以同時(shí)裝好多種飯菜映琳,神奇吧!蜘拉!
來吧萨西!然我們一起領(lǐng)略一下數(shù)組的神奇。常見的數(shù)組有三種旭旭,偽數(shù)組谎脯、數(shù)組、關(guān)聯(lián)數(shù)組持寄。
偽數(shù)組
偽數(shù)組應(yīng)該是AutoHotkey中特有的概念源梭,每個(gè)偽數(shù)組實(shí)際上只是一系列連續(xù)編號(hào)的變量或函數(shù)的集合娱俺,它們的每一個(gè)被視為偽數(shù)組的“元素”。AutoHotkey 內(nèi)部不會(huì)以任何方式把這些元素鏈接在一起废麻。任何接受 OutputVar
或能賦值的命令都可以用來創(chuàng)建偽數(shù)組矢否。
最簡(jiǎn)單的例子是使用賦值運(yùn)算符(:=)
,如下所示:
Array%j% := A_LoopField
通過在索引間使用自選分隔符可以創(chuàng)建多維偽數(shù)組脑溢,例如:
Array%j%_%k% := A_LoopReadLine
操作偽數(shù)組下面的例子演示了如何創(chuàng)建和訪問偽數(shù)組僵朗,這里是從文本文件獲取一系列的名稱:
; 例1:寫入數(shù)據(jù)到偽數(shù)組:
ArrayCount := 0
Loop, Read, C:\Test.txt ; 循環(huán)獲取文件中的每行,一次一行屑彻。
{
ArrayCount += 1 ; 記錄偽數(shù)組中的項(xiàng)目數(shù)验庙,這里不記錄后面獲取不方便。
Array%ArrayCount% := A_LoopReadLine ; 把此行保存到偽數(shù)組中的下一個(gè)元素社牲。
}
; 例2:從偽數(shù)組中讀确嘌Α:
Loop, %ArrayCount%
{
; 下一行使用 := 運(yùn)算符獲取偽數(shù)組元素:
element := Array%A_Index% ; A_Index 是內(nèi)置變量。
MsgBox, % "索引號(hào)" . A_Index . "的元素的值為" . Array%A_Index%
}
看過這兩個(gè)例子后搏恤,里面的操作中我們只是連續(xù)的操作變量罷了违寿,與操作普通變量在性質(zhì)上沒有區(qū)別。唯一的區(qū)別是名稱熟空,這系列變量的名稱一般后面部分為數(shù)字藤巢,比較典型的如 StringSplit、WinGet List
及 RegExMatch
這些命令創(chuàng)建的偽數(shù)組息罗。還有些命令雖然會(huì)創(chuàng)建一系列變量掂咒,變量的名稱卻不是以數(shù)字結(jié)尾,如 GuiControlGet Pos迈喉、SysGet
等绍刮。
數(shù)組
簡(jiǎn)單數(shù)組創(chuàng)建數(shù)組:
Array := [Item1, Item2, ..., ItemN]
Array := Array(Item1, Item2, ..., ItemN)
獲取項(xiàng):
Value := Array[Index]
對(duì)項(xiàng)進(jìn)行賦值:
Array[Index] := Value
插入一個(gè)或多個(gè)東東到給定序號(hào)位置:
Array.InsertAt(Index, Value, Value2, ...)
追加一個(gè)或多個(gè)東東:
Array.Push(Value, Value2, ...)
移除項(xiàng):
RemovedValue := Array.RemoveAt(Index)
移除最后一項(xiàng):
RemovedValue := Array.Pop()
如果數(shù)組不是空的, 那么 MinIndex
和MaxIndex/Length
分別返回?cái)?shù)組中當(dāng)前使用的最小和最大的索引. 由于最小的索引幾乎總是 1, 所以 MaxIndex
經(jīng)常返回項(xiàng)目數(shù). 如果沒有整數(shù)鍵, MaxIndex
返回空而 Length
返回 0 ,對(duì)數(shù)組內(nèi)容進(jìn)行依次循環(huán)可以通過索引或 For
循環(huán)實(shí)現(xiàn)。
例如:
array := ["one", "two", "three"]
; 從 1 到項(xiàng)目數(shù)進(jìn)行重復(fù):
Loop % array.Length()
MsgBox % array[A_Index]
; 枚舉數(shù)組內(nèi)容:
For index, value in array
MsgBox % "Item " index " is '" value "'"
關(guān)聯(lián)數(shù)組
關(guān)聯(lián)數(shù)組是一種數(shù)據(jù)結(jié)構(gòu)挨摸,本質(zhì)上是一種特殊的對(duì)象孩革。操作關(guān)聯(lián)數(shù)組自包含關(guān)聯(lián)數(shù)組可以使用以下兩種創(chuàng)建
<pre>Array := {KeyA: ValueA, KeyB: ValueB, ..., KeyZ: ValueZ}
Array := Object("KeyA", ValueA, "KeyB", ValueB, ..., "KeyZ", ValueZ)</pre>
例如:
; 創(chuàng)建數(shù)組后,初始為空:
Array := Object()
; 寫入數(shù)據(jù)到數(shù)組:
Loop, Read, C:\Guest List.txt ; 依次獲取文件中的每行文本得运。
{
Array.Insert(A_LoopReadLine) ; 添加到數(shù)組中膝蜈。
}
; 從數(shù)組中讀取數(shù)據(jù),在一般情況下建議使用這種方式(即 for 循環(huán)):
for index, element in Array
{
MsgBox, % "索引號(hào)為" . index . "的元素的值為" . element
}
這個(gè)例子僅演示了對(duì)象提供的功能中很小的一部分澈圈,還可以可以設(shè)置彬檀、獲取、插入瞬女、移除和枚舉項(xiàng)目。除了數(shù)字努潘,還可以把字符串和對(duì)象作為鍵使用诽偷。對(duì)象可以作為值存儲(chǔ)到其他對(duì)象中并且可以作為函數(shù)參數(shù)或返回值傳遞坤学。對(duì)象還可以用新功能進(jìn)行擴(kuò)展。
For 循環(huán)與 Loop 循環(huán)
對(duì)于這樣特殊的關(guān)聯(lián)數(shù)組报慕,還可以把上面的 For 循環(huán)替換為 Loop 循環(huán):
; 使用傳統(tǒng)方式
Loop, % Array.MaxIndex()
{
; 使用“Loop”深浮,索引必須是連續(xù)的數(shù)字,從 1 到數(shù)組中元素的個(gè)數(shù)(或者必須在循環(huán)中進(jìn)行計(jì)算)眠冈。
MsgBox, % "索引號(hào)為" . A_Index . "的元素的值為" . Array[A_Index]
}
實(shí)際上不建議使用 Loop 對(duì)關(guān)聯(lián)數(shù)組進(jìn)行循環(huán)操作(很蹩腳)飞苇,上面的例子中數(shù)組的索引從 1 開始且是連續(xù)的整數(shù),所以可以使用 Loop 循環(huán)蜗顽。然而布卡,關(guān)聯(lián)數(shù)組中的鍵可以為字符串、整數(shù)或?qū)ο蠊透牵词规I為整數(shù)時(shí)還可能是稀疏分布的忿等,例如{1:"a",1000:"b"}
,在這些一般情況下都無法使用 Loop 代替崔挖。
數(shù)組贸街、偽數(shù)組與關(guān)聯(lián)數(shù)組的之間的比較和應(yīng)用
盡管 Insert() 和枚舉數(shù)有它們的用途, 不過一些用戶可能會(huì)發(fā)現(xiàn)使用它們比用更傳統(tǒng)的方式容易些。下面的例子中把偽數(shù)組和關(guān)聯(lián)數(shù)組的操作方式進(jìn)行比較狸相,其中注釋中的為偽數(shù)組的操作方式:
; 與變量可直接使用不同薛匪,數(shù)組在使用前必須初始化:
Array := Object()
; Array%j% := A_LoopField
Array[j] := A_LoopField
; Array%j%_%k% := A_LoopReadLine
Array[j, k] := A_LoopReadLine
ArrayCount := 0
Loop, Read, C:\Guest List.txt
{
ArrayCount += 1
; Array%ArrayCount% := A_LoopReadLine
Array[ArrayCount] := A_LoopReadLine
}
Loop, %ArrayCount%
{
; element := Array%A_Index%
element := Array[A_Index]
; MsgBox % "Element number " . A_Index . " is " . Array%A_Index%
MsgBox, % "Element number " . A_Index . " is " . Array[A_Index]
}
這個(gè)是幫助中的例子,但實(shí)際意義不大脓鹃,因?yàn)樗且詡螖?shù)組的方式在偽數(shù)組的功能上進(jìn)行的比較蛋辈。例如使用 ArrayCount
變量保存數(shù)組元素個(gè)數(shù),我們知道這對(duì)于關(guān)聯(lián)數(shù)組是多余的将谊,它的元素個(gè)數(shù)是由程序維護(hù)冷溶,可以直接使用 MaxIndex()
方法獲取,而且獲取值時(shí)無需通過元素個(gè)數(shù)尊浓,可直接 for
循環(huán)逞频。幫助中提到這個(gè)比較會(huì)“讓大家更容易從原來使用偽數(shù)組的習(xí)慣中過渡過來”,不過我個(gè)人認(rèn)為這樣做是否像用漢字標(biāo)出英語單詞的發(fā)音來學(xué)英語呢栋齿?
關(guān)聯(lián)數(shù)組使用與簡(jiǎn)單數(shù)組非常相似的語法. 事實(shí)上, 在 v1.x 中它們是相同的東西. 然而, 把 []
視為簡(jiǎn)單線性數(shù)組有助于保持其作用清晰, 并且改善您腳本與 AutoHotkey 未來版本的兼容性, 未來版本中可能改變實(shí)現(xiàn)方式.
小結(jié)
目前而言苗胀,在支持創(chuàng)建偽數(shù)組的命令中還是需要偽數(shù)組(偽數(shù)組存在的必要性),在其他地方關(guān)聯(lián)數(shù)組具有優(yōu)勢(shì)(關(guān)聯(lián)數(shù)組的功能強(qiáng)大瓦堵、使用方便)基协,即關(guān)聯(lián)數(shù)組尚無法完全取代偽數(shù)組(即使作為中間產(chǎn)物),盡管我推薦在一般情況下使用關(guān)聯(lián)數(shù)組菇用。