Scripting 脚本编写。字典查找如果不存在,是否仅添加一个关键字搜索?
我正在Scripting 脚本编写。字典查找如果不存在,是否仅添加一个关键字搜索?,scripting,dictionary,vbscript,scripting.dictionary,Scripting,Dictionary,Vbscript,Scripting.dictionary,我正在Scripting.Dictionary中查找键,以确保只向字典中添加一次键(及其项): If MyDict.Exists (Key) Then ' first internal key-value lookup Set Entry=MyDict.Item (Key) ' Second internal key->value lookup else Set Entry=New ItemType MyDict.Add Key,Entry End If ' Now I wo
Scripting.Dictionary
中查找键,以确保只向字典中添加一次键(及其项):
If MyDict.Exists (Key) Then ' first internal key-value lookup
Set Entry=MyDict.Item (Key) ' Second internal key->value lookup
else
Set Entry=New ItemType
MyDict.Add Key,Entry
End If
' Now I work on Entry...
Exists
在字典中查找键,Item()
也会这样做。因此,对于一个逻辑查找操作,我得到了两个键查找。难道没有更好的办法吗
项
属性的dox是
如果在尝试返回现有项时未找到项,则会出现一个新项
密钥已创建,其对应项保留为空。”
()
这是正确的,即查找不存在的键显然会使该键成为字典的一部分,可能关联项=空。
但是那有什么好处呢我如何使用它将其归结为一个查找操作?在项()
属性调用期间创建键后,如何设置空项?此代码和输出:
>> Set d = CreateObject("Scripting.Dictionary")
>> WScript.Echo 0, d.Count
>> If d.Exists("soon to come") Then : WScript.Echo 1, d.Count : End If
>> WScript.Echo 2, d.Count
>> d("soon to come") = d("soon to come") + 1
>> WScript.Echo 3, d.Count, d("soon to come")
>>
0 0
2 0
3 1 1
显示:
Set d(name)=object
-d(name)将在必要时创建键槽“name”,并且Set赋值将对象放入相应的值中(覆盖空对象或“old”对象(“指针”))if ! (oBJ = dicX( key )) {
oBJ = dicX( key ) = new ItemType()
}
oBJ.doSomething()
oBJ = dicX( key )
If IsEmpty( oBJ ) Then
dicX( key ) = New ItemType
oBJ = dicX( key )
End If
没有VBScript的设置vs.让讨厌的东西
if ! (oBJ = dicX( key )) {
oBJ = dicX( key ) = new ItemType()
}
oBJ.doSomething()
oBJ = dicX( key )
If IsEmpty( oBJ ) Then
dicX( key ) = New ItemType
oBJ = dicX( key )
End If
只会为新元素做额外的工作,但这一切都是白日梦
如果那些双重查找真的很重要(我怀疑这一点),你能给出一个论点吗
或者证据?),那么程序的总体设计就很重要了。例如:
如果你能把你的工作清单整理好,一切都会变得简单(参见我的工作清单中的/m:c)
样本)。诚然,我仍然不知道这种改变是否可能
对于您的特定任务
要进行试验的代码:
Dim dicX : Set dicX = CreateObject( "Scripting.Dictionary" )
Dim aKeys : aKeys = Split( "1 2 3 4 4 3 2 1 5" )
Dim sMode : sMode = "a"
Dim oWAN : Set OWAN = WScript.Arguments.Named
If oWAN.Exists( "m" ) Then sMode = oWAN( "m" )
Dim sKey, oBJ
Select Case sMode
Case "a"
For Each sKey In aKeys
If Not dicX.Exists( sKey ) Then
Set dicX( sKey ) = New cItemType.init( sKey )
End If
Set oBJ = dicX( sKey )
WScript.Echo oBJ.m_sInfo
Next
Case "b"
For Each sKey In aKeys
If IsEmpty( dicX( sKey ) ) Then
Set dicX( sKey ) = New cItemType.init( sKey )
End If
Set oBJ = dicX( sKey )
WScript.Echo oBJ.m_sInfo
Next
Case "c"
aKeys = uniqueList( aKeys )
For Each sKey In aKeys
Set dicX( sKey ) = New cItemType.init( sKey )
Set oBJ = dicX( sKey )
WScript.Echo oBJ.m_sInfo
Next
Case Else
WScript.Echo "Unknown /m:" & sMode & ", pick one of a, b, c."
End Select
WScript.Echo "----------"
For Each sKey In dicX.Keys
WScript.Echo dicX( sKey ).m_sInfo
Next
Dim g_ITCnt : g_ITCnt = 0
Class cItemType
Public m_sInfo
Public Function init( sKey )
Set init = Me
g_ITCnt = g_ITCnt + 1
m_sInfo = "Obj for " & sKey & " (" & g_ITCnt & ")"
End Function
End Class ' cItemType
Function uniqueList( aX )
Dim dicU : Set dicU = CreateObject( "Scripting.Dictionary" )
Dim vX
For Each vX in aX
dicU( vX ) = Empty
Next
uniqueList = dicU.Keys
End Function
样本输出:
/m:a
Obj for 1 (1)
Obj for 2 (2)
Obj for 3 (3)
Obj for 4 (4)
Obj for 4 (4)
Obj for 3 (3)
Obj for 2 (2)
Obj for 1 (1)
Obj for 5 (5)
----------
Obj for 1 (1)
Obj for 2 (2)
Obj for 3 (3)
Obj for 4 (4)
Obj for 5 (5)
==================================================
xpl.vbs: Erfolgreich beendet. (0) [0.07031 secs]
/m:c
Obj for 1 (1)
Obj for 2 (2)
Obj for 3 (3)
Obj for 4 (4)
Obj for 5 (5)
----------
Obj for 1 (1)
Obj for 2 (2)
Obj for 3 (3)
Obj for 4 (4)
Obj for 5 (5)
================================================
xpl.vbs: Erfolgreich beendet. (0) [0.03906 secs]
定时差异可能是由/m:c的输出减少引起的
模式,但它强调了不经常做某事的重要性
那是必要的 对我来说,关键问题是VBScript迫使我们对对象使用
Set
,而Empty
不是对象。我过去使用的一个技巧是使用Array
函数为值创建一个临时占位符。然后我可以检查数组,看看值是否是对象。适用于您的示例:
tempArr = Array(dict.Item(key))
If IsEmpty(tempArr(0)) Then
' new entry
Set entry = New MyClass
' can't use Add because the key has already been implicitly created
Set dict.Item(key) = entry
Else
' existing entry
Set entry = tempArr(0)
End If
不过,在本例中,您并没有取消双重查找,而是将其从“现有条目”案例移到了“新条目”案例。>这种小规模的自动激活不能用于对象…我想要实现的是,如果存在现有条目,则获取对该条目的引用,如果不存在,则添加一个新条目,然后在处理结果条目(现有条目或新添加的条目)时,无需在此过程中进行两次键->值查找尝试。@TheBlastOne:对不起,也许我很笨,但我不理解您的要求,特别是当您的示例代码将条目对象(ItemType)从稀薄的空气中拉出时。你怎么填字典?示例代码的上下文是什么?ItemType是空谈,它与对象类型无关。特定上下文是构建表信息的代码,字典为每个QTP表(=键)包含一个自定义对象(=项),其中包含主键(=键)和行ID(=项)的子字典。引用的代码用于检查手头是否已有QTP图纸的自定义对象,如果没有,则创建并添加一个自定义对象。然后,对自定义对象进行操作。所有这些都无关紧要。问题是:对于Scripting.Dictionary,是否可以检索现有项(如果存在)并添加一个(如果不存在),然后在这两种情况下都接收对该项的引用,而不触发多个键->值查找?出于性能原因,我试图避免冗余(双)查找操作。(是的,我正在优化QTP脚本代码:o()是的,我也这么认为。还尝试了在错误恢复下比较对象和空。