如何在 VBScript 中向现有数组添加项目?
有没有相当于Javascript中push功能的VBScript?
即
myArray 有三个项目:“苹果”、“橙子”和“香蕉”,我想将“西瓜”添加到数组的末尾。
数组在 VBScript 中不是很动态。您必须使用 ReDim Preserve 语句来增加现有数组,以便它可以容纳额外的项目:
ReDim Preserve yourArray(UBound(yourArray) + 1)
yourArray(UBound(yourArray)) = "Watermelons"
让您轻松复制和粘贴
' add item to array
Function AddItem(arr, val)
ReDim Preserve arr(UBound(arr) + 1)
arr(UBound(arr)) = val
AddItem = arr
End Function
像这样使用
a = Array()
a = AddItem(a, 5)
a = AddItem(a, "foo")
有几种方法,不包括自定义 COM 或 ActiveX 对象
通过下面的代码,我发现Redim Preserve在54000以下最快,Dictionary在54000到690000之间最快,Array List在690000以上最快。由于排序和数组转换,我倾向于使用ArrayList进行推送。
user326639 提供了 FastArray,这几乎是最快的。
字典对于搜索值和返回索引(即字段名称)或分组和聚合(直方图、分组和添加、分组和连接字符串、分组和推送子数组)很有用。对键进行分组时,设置 CompareMode 的大小写/敏感度,并在“add”之前检查“exists”属性。
Redim 对于一个数组不会节省太多时间,但对于数组字典很有用。
'pushtest.vbs
imax = 10000
value = "Testvalue"
s = imax & " of """ & value & """"
t0 = timer 'ArrayList Method
Set o = CreateObject("System.Collections.ArrayList")
For i = 0 To imax
o.Add value
Next
s = s & "[AList " & FormatNumber(timer - t0, 3, -1) & "]"
Set o = Nothing
t0 = timer 'ReDim Preserve Method
a = array()
For i = 0 To imax
ReDim Preserve a(UBound(a) + 1)
a(UBound(a)) = value
Next
s = s & "[ReDim " & FormatNumber(timer - t0, 3, -1) & "]"
Set a = Nothing
t0 = timer 'Dictionary Method
Set o = CreateObject("Scripting.Dictionary")
For i = 0 To imax
o.Add i, value
Next
s = s & "[Dictionary " & FormatNumber(timer - t0, 3, -1) & "]"
Set o = Nothing
t0 = timer 'Standard array
Redim a(imax)
For i = 0 To imax
a(i) = value
Next
s = s & "[Array " & FormatNumber(timer - t0, 3, -1) & "]" & vbCRLF
Set a = Nothing
t0 = timer 'Fast array
a = array()
For i = 0 To imax
ub = UBound(a)
If i>ub Then ReDim Preserve a(Int((ub+10)*1.1))
a(i) = value
Next
ReDim Preserve a(i-1)
s = s & "[FastArr " & FormatNumber(timer - t0, 3, -1) & "]"
Set a = Nothing
MsgBox s
' 10000 of "Testvalue" [ArrayList 0.156][Redim 0.016][Dictionary 0.031][Array 0.016][FastArr 0.016]
' 54000 of "Testvalue" [ArrayList 0.734][Redim 0.672][Dictionary 0.203][Array 0.063][FastArr 0.109]
' 240000 of "Testvalue" [ArrayList 3.172][Redim 5.891][Dictionary 1.453][Array 0.203][FastArr 0.484]
' 690000 of "Testvalue" [ArrayList 9.078][Redim 44.785][Dictionary 8.750][Array 0.609][FastArr 1.406]
'1000000 of "Testvalue" [ArrayList 13.191][Redim 92.863][Dictionary 18.047][Array 0.859][FastArr 2.031]
对上面的 FastArray 进行轻微更改:
'pushtest.vbs
imax = 10000000
value = "Testvalue"
s = imax & " of """ & value & """"
t0 = timer 'Fast array
a = array()
ub = UBound(a)
For i = 0 To imax
If i>ub Then
ReDim Preserve a(Int((ub+10)*1.1))
ub = UBound(a)
End If
a(i) = value
Next
ReDim Preserve a(i-1)
s = s & "[FastArr " & FormatNumber(timer - t0, 3, -1) & "]"
MsgBox s
如果我们确切地知道它何时发生变化,那么在 for 的每个循环中检查
UBound(a)
是没有意义的。
我已经更改了它,以便它在 for 开始之前检查
UBound(a)
,然后仅在每次调用 ReDim
时检查
在我的电脑上,旧方法花了 7.52 秒,imax 达到 1000 万。
新方法在 imax 也达到 1000 万次时花费了 5.29 秒,这意味着性能提升了 20% 以上(对于 1000 万次尝试,显然这个百分比与尝试次数有直接关系)
基于 Charles Clayton 的回答,但稍微简化了......
' add item to array
Sub AddItem(arr, val)
ReDim Preserve arr(UBound(arr) + 1)
arr(UBound(arr)) = val
End Sub
像这样使用
a = Array()
AddItem(a, 5)
AddItem(a, "foo")
这有点晚了,但无论如何,这也有点棘手
dim arrr
arr= array ("Apples", "Oranges", "Bananas")
dim temp_var
temp_var = join (arr , "||") ' some character which will not occur is regular strings
if len(temp_var) > 0 then
temp_var = temp_var&"||Watermelons"
end if
arr = split(temp_var , "||") ' here you got new elemet in array '
for each x in arr
response.write(x & "<br />")
next'
查看并告诉我这是否可行 或者最初将所有数据保存在字符串中,然后拆分为数组
不是答案或者为什么“棘手”不好:
>> a = Array(1)
>> a = Split(Join(a, "||") & "||2", "||")
>> WScript.Echo a(0) + a(1)
>>
12