【AHK】打造炒股利器系列——用关联数组(也称为对象或字典)继续简化语音报时器
上一篇 【AHK】打造炒股利器系列——用数组和循环来简化语音报时器 中用Array
和Loop
简化了多行if
语句,本文使用 AutoHotkey v1 中的关联数组(也称为对象或字典)来进一步简化这个脚本。这样可以将时间和消息直接关联起来,使代码更加简洁和易于维护。以下是使用关联数组简化后的脚本:
#Persistent
#SingleInstance Force
/**
*【AHK】打造炒股利器系列——用关联数组(也称为对象或字典)继续简化语音报时器
* 作者:liuyukuan
* 版权声明:未经授权,不得转载
* 最新版发布在:https://blog.csdn.net/liuyukuan
*/
; 使用关联数组存储时间和对应的消息
timeMessages := { "09:00:00": "早盘下载数据"
, "09:15:00": "开始集合竞价"
, "09:25:00": "距开盘还有五分钟"
, "09:30:00": "上午开盘"
, "11:30:00": "中午收盘"
, "13:00:00": "下午开盘"
, "14:45:00": "距收盘还有十五分钟"
, "15:00:00": "全天收盘" }
; 创建 一个 字转语音(TTS )COM 对象
Aladdin := ComObjCreate("sapi.spvoice")
; 设置定时器,每 0.5 秒运行一次
SetTimer, 定时器, 500
return
定时器:
FormatTime, 当前时间,, HH:mm:ss
; 检查当前时间是否在关联数组中
if (timeMessages.HasKey(当前时间))
{
Aladdin.Speak(timeMessages[当前时间])
}
return
上一篇讲到的简单数组可以使用Array函数
或方括号[]
语法创建,而本篇中用到的关联数组使用Object函数
或大括号{}
语法创建。
知识点
- 一、关联数组
- 1、获取项:
- 2、对项进行赋值:
- 3、使用 Delete 方法移除项:
- 4、枚举项:
- 二、对象Object
- 1、创建对象
- 方括号[]语法
- 大括号{}语法
- Array函数
- Object函数
- 2、使用对象
- 2.1 设置值:
- 方括号表示法
- 句点表示法
- 2.2 检索值:
- 方括号表示法
- 句点表示法
- 2.3 增加新的键和值:
- 方括号表示法
- 句点表示法
- InsertAt(在..插入) 法
- Push(压入) 法
- 2.4 移除键和值:
- 用空白填充值`Banana.Consistency := ""`
- 删除法
- Pop(弹出) 法
- RemoveAt(在..删除) 方法
一、关联数组
关联数组是包含一组键(每个键是唯一的) 和一组值的对象, 其中每个键和一个值关联。 键可以为字符串,整数或对象,而值可以为任何类型。 关联数组可以用如下方法创建:
Array := {KeyA: ValueA, KeyB: ValueB, ..., KeyZ: ValueZ}
Array := Object("KeyA", ValueA, "KeyB", ValueB, ..., "KeyZ", ValueZ)
使用 {key:value} 表示法时, 对于仅由单词字符组成的键, 其两边的引号标记是可选的. 可以使用任何表达式作为键, 但使用变量作为键时, 它必须包围在小括号中. 例如, {(KeyVar): Value} 和 {GetKey(): Value} 都是合法的.
1、获取项:
Value := Array[Key]
2、对项进行赋值:
Array[Key] := Value
3、使用 Delete 方法移除项:
RemovedValue := Array.Delete(Key)
4、枚举项:
array := {ten: 10, twenty: 20, thirty: 30}
For key, value in array
MsgBox %key% = %value%
关联数组可以是稀疏分布的 - 即 {1:“a”,1000:“b”} 仅包含两个键值对, 而不是 1000.
到现在, 您也许已经注意到关联数组使用与简单数组非常相似的语法。 事实上, 在 v1 中它们是相同的东西。然而, 把 []
视为简单线性数组有助于保持其作用清晰。
二、对象Object
对象是一种组织数据以实现更高效使用的方法。有时候对象被当作数组,在这重点声明一下所有的数组都是对象。对象基本上是变量的集合。变量的名称叫做 “键”, 变量的内容叫做 “值”。
当你听到人们把一个对象叫做 数组
时, 说明这个对象的键是从 1 开始递增的连续自然数。当你听到人们把一个对象叫做 关联数组
, 说明这个对象的键要么使用字符串(或文本), 要么使用不连续的数字,有时可能是两者的混合。一个对象的键和值可以是什么,没有任何限制, 它们甚至可以是另一个数组!如果一个对象的值也是数组, 我们把它叫做 嵌套数组,这个我们以后再解释。
您可能想要使用对象的原因有很多,一些例子:
- 当你需要描述一组有序列表时, 比如购物清单(这种情况最好使用索引数组)
- 当你需要描述一组事物而每样事物都有自己的名称时, 比如描述水果的特性(这种情况最好使用关联数组)
- 当你需要描述一个图形方阵时,比如一个棋盘游戏(这种情况最好使用嵌套对象)
1、创建对象
我们有很多方法可以创建对象, 下面介绍最常用的几种方法:
方括号[]语法
MyObject := ["one", "two", "three", 17]
这被称为 “简单数组”,是一个表示项目列表的对象,索引号为默认的从 1 开始连续递增的自然数。 在本例中, 值 “one” 存储在对象键 1(又叫做索引号1), 值 17 存储在对象键 4(又叫做索引号 4)。
大括号{}语法
Banana := {"Color": "Yellow", "Taste": "Delicious", "Price": 3}
这被称为 “关联数组”, 关联数组是数据的集合, 其中每个条目都有自己的名称。也称为字典, 在这个例子中, 值 “Yellow” 存储在对象键 “Color” 中. 同样的, 值 3 存储在对象键 “Price” 中.
Array函数
MyObject := Array("one", "two", "three", 17)
这种方式跟方括号语法形式一样, 区别仅仅是采用了函数的形式.
Object函数
Banana := Object("Color", "Yellow", "Taste", "Delicious", "Price", 3)
这种方式跟大括号语法形式一样, 区别仅仅是采用了函数的形式.
请注意, 所有这些方法都创建了同一样东西(也就是对象), 区别仅仅是对象的键不一样。
2、使用对象
使用对象有很多方式, 包括检索值,设置值, 添加更多的值等等。
2.1 设置值:
方括号表示法
Banana["Color"] := "Yellow"
在对象中设置值跟设置变量的值一样简单. 你需要做的是把方括号所代表的值在表达式赋值运算符 := 的左边。
句点表示法
Banana.Color:= "Yellow"
和上面一样对, 但是用点(.) 符号。
2.2 检索值:
方括号表示法
Value := Banana["Color"]
这允许你使用表达式作为键从对象中获取值. 在这个例子中, 我使用表达式 “Color”, 不要惊讶我仅使用键 Color 就会得到一个包含单词 “Yellow” 的值, 因为我们事先(在上一节) 就设置了键 Color。
句点表示法
Value := Banana.Color
仅允许使用原样的字串作为键名。 在句点表示法中, 键名不能使用变量。
2.3 增加新的键和值:
方括号表示法
MyObject["NewerKey"] := 3.1415
想要直接添加一对键和值, 只需设置一个尚不存在的键即可.
句点表示法
MyObject.NewKey := "Shiny"
和上面一样, 但是用点符号.
InsertAt(在…插入) 法
MyObject.InsertAt(Index, Value1, Value2, Value3...)
Index(索引) 为任意整数键. 这会将所有更高的整数键的索引向上移动插入值的数量, 即使是空缺的也一样(例如, 假设只有键 1 和 100 存在, 当插入一个值到第 50 个键的位置时, 将导致原来位于 100 的键的索引变成 101).
Push(压入) 法
MyObject.Push(Value1, Value2, Value3...)
“追加” 值到数组 MyObject 的尾部。换句话说, 它将插入的值放在 最大整数键 + 1 的位置。
2.4 移除键和值:
用空白填充值Banana.Consistency := ""
最简单的删除值的方法就是用空白填充. 你可以将其赋值为 “”(两个连续的双引号), 也就是常说的 空字符串. 这不会删除键, 但是它将使值看起来与从未赋值一样. 可以通过使用 HasKey 方法得知键依然存在, 而且键也会出现在 For 循环中. (我们一会再解释 For 循环)
删除法
RemovedValue := MyObject.Delete(AnyKey)
这个方法将删除 键 和 值。并把MyObject[AnyKey] 先前的值存储在 RemovedValue 中.
NumberOfRemovedKeys := MyObject.Delete(FirstKey, LastKey)
允许你删除 FirstKey 和 LastKey 之间的一系列的编号/整数或字符串键。它返回的值将是被删除的键的数量, 如果你的键之间有间隙, 这是有用的(例如你指定键从 1 到 4, 但是键 2 不存在, 这将设置 NumberOfRemovedKeys 为 3, 因为只有三个键被移除).
Pop(弹出) 法
MyObject.Pop()
这将删除最高的整数键, 并返回这个键对应的值. 而且这种形式不会影响其他键的索引顺序(因为没有比它更高的序列了).
RemoveAt(在…删除) 方法
RemovedValue := MyObject.RemoveAt(Index)
NumberOfRemovedKeys := MyObject.RemoveAt(Index, Length)
这将移除从 Index 到 Index + Length - 1(包含) 之间的所有键(例如 Index 为 5, Length 为 3, 则将删除键 5, 6, 7 这三个键). 如果 Length 省略则默认为 1. 移除这些键之后, 更高数字或整数的键将向下填充空缺, 所以如果有个值位于 Index + Length 那么它现在的位置就是 Index. 这很像 InsertAt 方法操作多个指定值的操作.