gpt4 book ai didi

Scripting.Dictionary Lookup-add-if-not-present 只有一键搜索?

转载 作者:行者123 更新时间:2023-12-04 14:42:11 25 4
gpt4 key购买 nike

我正在查找 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 () 也是这样做的。所以我得到了一个逻辑查找操作的两个关键查找。有没有更好的办法?

Item 属性的 dox 说

"If key is not found when attempting to return an existing item, a new key is created and its corresponding item is left empty." (MSDN)

这是真的,即查找一个不存在的键显然使这个键成为字典的一部分,可能关联的项目=空。但那有什么用呢? 如何使用它来将其归结为一个查找操作?如何在 Item () 属性调用期间创建键后设置空项?

最佳答案

此代码和输出:

>> 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

显示:

  1. 使用 .Exists 查找不存在的键不会将键添加到字典中(.Count 在#2 处仍然为 0)
  2. 通过 .Item 或 () 访问不存在的键 - 如我的示例代码中赋值的右侧 - 将键/空对添加到字典中;对于某些任务(例如频率计数),这个“有效”,因为 Empty 在字符串连接中被额外视为 0 或“”。这个小尺度autovivification不能用于对象(没有合适的方法将 Empty 映射到程序员想到的任何对象,也没有像 Python 或 VBScript 中的 Ruby 那样的默认魔法)
  3. 如果你必须维护一个命名对象的字典并且可以同时访问名称和它的对象,你可以只写 Set d(name) = object - d(name) will如有必要,创建键槽“name”,Set 赋值会将对象放入相应的值(覆盖 Empty 或“旧”对象(“指针”))。

如果您附加一些关于您真正想要实现的目标的详细信息,我愿意添加到这个答案中。

添加:

如果您(逻辑上)处理具有重复键的列表并且必须添加新的动态地指向字典,你无法避免双重查找,因为您需要检查是否存在 (1.0) 并分配 (2.0) (也许是新的创建并分配 (1.5)) 对象到您的工作变量(请参阅我的/m:a 或/m:b示例代码)。带有传递值的语句的其他语言可能允许像

if ! (oBJ = dicX( key )) {
oBJ = dicX( key ) = new ItemType()
}
oBJ.doSomething()

没有 VBScript 的 Set vs. Let 类似的东西

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 的输出减少造成的模式,但它强调不要经常做某事的重要性那么必要的。

关于Scripting.Dictionary Lookup-add-if-not-present 只有一键搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6910996/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com