ASP Dictionary
Scripting.Dictionary 的增删改查、存在判断、遍历与比较模式。
基本操作
<%
Dim d
Set d = Server.CreateObject("Scripting.Dictionary")
d.Add "name", "Ada"
d.Add "role", "admin"
d("age") = 36 ' 也可以直接赋值
Response.Write d("name") & "<br>"
Response.Write d.Count & " 项<br>"
' 改
d("role") = "editor"
' 判断存在(必须!)
If d.Exists("email") Then
Response.Write d("email")
Else
Response.Write "没有 email"
End If
' 删
d.Remove "age"
d.RemoveAll
%>Ada
3 项
没有 emaild("missing") does not error — it creates the key and returns Empty. Always If d.Exists(k) before reading, or the dictionary quietly fills with empty keys.
遍历
<%
Dim k
For Each k In d.Keys
Response.Write k & " = " & d(k) & "<br>"
Next
' 单独拿数组
Dim keys, items
keys = d.Keys
items = d.Items
Response.Write UBound(keys) + 1 & " 个键"
%>name = Ada
role = editor
2 个键d.Keys and d.Items return arrays usable with UBound and Split. Do not Remove the current item while enumerating — it upsets the enumerator and skips entries or errors.
CompareMode
<%
d.CompareMode = 1 ' 1 = Text(不区分大小写),0 = Binary(默认)
d("Name") = "Ada"
Response.Write d.Exists("name") ' True(Text 模式)
%>TrueThe default Binary mode is case-sensitive, so d("Name") and d("name") are separate keys. CompareMode can only be set while the dictionary is empty; changing it later raises an error.
实用场景
<%
' 统计词频
Dim words, w, freq
words = Split("asp is easy asp is fast", " ")
Set freq = Server.CreateObject("Scripting.Dictionary")
For Each w In words
If freq.Exists(w) Then
freq(w) = freq(w) + 1
Else
freq(w) = 1
End If
Next
Dim k
For Each k In freq.Keys
Response.Write k & ":" & freq(k) & "<br>"
Next
%>asp:2
is:2
easy:1
fast:1去重
<%
Dim seen, out_, v
Set seen = Server.CreateObject("Scripting.Dictionary")
out_ = ""
For Each v In Array("a", "b", "a", "c", "b")
If Not seen.Exists(v) Then
seen.Add v, True
out_ = out_ & v & " "
End If
Next
Response.Write Trim(out_)
%>a b cDictionary is not thread-safe and does not survive a request unless stored in Application or Session. When stored in Application, lock around reads and writes or concurrent access loses keys or crashes.与数组的取舍
| Dictionary | ||
|---|---|---|
| Lookup | arr(i),快 | d(key),哈希,快 |
| Lookup by value | 要循环遍历 | Exists 直接判 |
| Order | 有序 | 无序(插入顺序不保证) |
| Size | 固定或 ReDim | 自动增长 |
基本操作
<%
Dim d
Set d = Server.CreateObject("Scripting.Dictionary")
d.Add "name", "Ada"
d.Add "role", "admin"
d("age") = 36 ' 也可以直接赋值
Response.Write d("name") & "<br>"
Response.Write d.Count & " 项<br>"
' 改
d("role") = "editor"
' 判断存在(必须!)
If d.Exists("email") Then
Response.Write d("email")
Else
Response.Write "没有 email"
End If
' 删
d.Remove "age"
d.RemoveAll
%>Ada
3 项
没有 emaild("不存在的键") 不会报错,而是新建一个键并返回 Empty。所以读之前必须 If d.Exists(k),否则字典里会悄悄多出一堆空键。
遍历
<%
Dim k
For Each k In d.Keys
Response.Write k & " = " & d(k) & "<br>"
Next
' 单独拿数组
Dim keys, items
keys = d.Keys
items = d.Items
Response.Write UBound(keys) + 1 & " 个键"
%>name = Ada
role = editor
2 个键d.Keys 和 d.Items 返回的是数组,可以和 UBound、Split 一起用。遍历时不要 Remove 当前项——会打乱枚举器,结果是跳过某些项或报错。
CompareMode
<%
d.CompareMode = 1 ' 1 = Text(不区分大小写),0 = Binary(默认)
d("Name") = "Ada"
Response.Write d.Exists("name") ' True(Text 模式)
%>True默认 Binary 模式区分大小写,d("Name") 和 d("name") 是两个键。CompareMode 只能在字典为空时设置,加了第一项之后再改会报错。
实用场景
<%
' 统计词频
Dim words, w, freq
words = Split("asp is easy asp is fast", " ")
Set freq = Server.CreateObject("Scripting.Dictionary")
For Each w In words
If freq.Exists(w) Then
freq(w) = freq(w) + 1
Else
freq(w) = 1
End If
Next
Dim k
For Each k In freq.Keys
Response.Write k & ":" & freq(k) & "<br>"
Next
%>asp:2
is:2
easy:1
fast:1去重
<%
Dim seen, out_, v
Set seen = Server.CreateObject("Scripting.Dictionary")
out_ = ""
For Each v In Array("a", "b", "a", "c", "b")
If Not seen.Exists(v) Then
seen.Add v, True
out_ = out_ & v & " "
End If
Next
Response.Write Trim(out_)
%>a b cDictionary 不是线程安全的,也不能跨请求保存(除非塞进 Application / Session)。塞进 Application 时读写都要 Lock,否则并发下会丢键甚至崩溃。与数组的取舍
| Array | Dictionary | |
|---|---|---|
| 按索引查 | arr(i),快 | d(key),哈希,快 |
| 按值查 | 要循环遍历 | Exists 直接判 |
| 顺序 | 有序 | 无序(插入顺序不保证) |
| 容量 | 固定或 ReDim | 自动增长 |