このコードと出力:
>> 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
ショー:
- .Existsを使用して存在しないキーを検索しても、キーはディクショナリに追加されません(.Countは#2でまだ0です)
- サンプルコードの割り当ての右側にあるように、.Itemまたは()を介して存在しないキーにアクセスすると、キーと空のペアが辞書に追加されます。一部のタスク(頻度カウントなど)では、これは「機能」します。これは、空が追加で0として、または文字列連結で「」として扱われるためです。この小規模な自動活性化はオブジェクトには使用できません(Emptyをプログラマーが考えているオブジェクトにマップする適切な方法はなく、PythonやVBScriptのRubyのようなデフォルトの魔法もありません)
- 名前付きオブジェクトのディクショナリを維持する必要があり、名前とそのオブジェクトに同時にアクセスできる場合は、次のように記述できます。
Set d(name) = object
-d(name)は、必要に応じてキースロット「name」を作成し、Set割り当てによってオブジェクトが配置されます。対応する値に変換します(Emptyまたは'old'オブジェクト('pointer')を上書きします)。
あなたが本当に達成したいことについていくつかの詳細を追加するならば、私はこの答えに喜んで追加します。
追加した:
重複するキーのリストで(論理的に)作業し、その場で新しいオブジェクトをディクショナリに追加する必要がある場合、存在(1.0)を確認して(2.0)を割り当てる必要があるため、二重ルックアップを回避することはできません。 (おそらく新しく作成され割り当てられた(1.5))オブジェクトを作業変数に追加します(サンプルコードの/ m:aまたは/ m:bを参照)。値を提供するステートメントを持つ他の言語では、次のようなことが可能になる場合があります
if ! (oBJ = dicX( key )) {
oBJ = dicX( key ) = new ItemType()
}
oBJ.doSomething()
そしてVBScriptのセットなしでvs.
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モードの出力の低下が原因ですが、必要以上に頻繁に何かを行わないことの重要性を強調しています。