scriptingdictionaryvbscriptscripting.dictionary

Scripting.Dictionary Lookup-add-if-not-present with only one key search?


I am looking up keys in a Scripting.Dictionary to make sure I add them (and their items) only once to the 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 looks up the key in the dictionary, and Item () does it, too. So i get two key lookups for one logical lookup operation. Isn't there a better way?

The dox for the Item property say

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

This is true, i.e. looking up a non-existant key obviously makes this key part of the dictionary, probably with associated item = empty. But what is that good for? How could I use this to boil it down to one lookup operation? How can I set the empty item after creating the key during the Item () property call?


Solution

  • The key problem to me is the fact that VBScript forces us to use Set with objects, and Empty is not an object. One trick that I've used in the past to get around this is to use the Array function to create a temporary placeholder for the value. Then I can check the array to see if the value is an object or not. Applied to your example:

    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
    

    In this case, though, you haven't eliminated the double lookup, but moved it from the "existing entry" case to the "new entry" case.