Using a Dictionary as an Array
A dictionary is a type of collection known as an associative array. With it, you can manage arrays of named values. Let's look at how we can use this instead of VBScript's dynamic arrays. There are two distinct approaches, depending on whether the data we collect has duplicate values. For general background information about the dictionary (as well as another approach to using it instead of a VBScript array), see "The Scripting Dictionary Makes It Easy" (August 2003, InstantDoc ID 39312).
Listing 3 demonstrates using a dictionary to collect data that might contain duplicate items. Instead of creating an Ips array as we did in Listing 2, we create a dictionary instance, as shown at callout A in Listing 3.
Every time we find a new IP address, we add a new entry as shown at callout B in Listing 3. The Count property represents the number of elements in the dictionary, so on its first pass, the statement at callout B reduces to
Ips(0) = Ip
This is much simpler. If we want to use a VBScript array function such as Join on the information after we're done, we will need to extract the array of values, but we can do this in one line as well, shown at callout C in Listing 3. The Items collection is a native VBScript array.
The code in Listing 4 shows an even simpler approach. The keys of a dictionary must be unique—we can't have two keys named 0, for example—but if we don't need to preserve duplicate values, we can store the values in the keys. At callout A in Listing 4, we add each IP address as a key with a null string as the value. If the data we're collecting has duplicate values, duplicate items will be silently updated. After we're done collecting data, we can get a real array of IP addresses by calling Ips.Keys, as shown at callout B in Listing 4.
The Best Solution
Scripters have begun using dictionaries more frequently in the past few years, as "Understanding VBScript: The Dictionary Object—An Alternative to Arrays" (June 2000, InstantDoc ID 8797) points out. However, I still encounter dynamic arrays much more often than dictionaries in VBScript code.
When deciding whether to use a dynamic array or a dictionary, it's important to know that there's nothing sacred about VBScript arrays. You aren't required to use them simply because they're included in the language. Eric Lippert, the Microsoft developer who owned VBScript over most of theWindows Script Host (WSH) development life cycle, regularly recommends using a dictionary instead.
If you're interested in some of the internals of VBScript, he occasionally discusses items such as the history of VBScript development in his "Fabulous Adventures in Coding" blog (http://blogs.msdn.com/ericlippert). A significant point is that elements of VBScript such as its array handling usually are designed for compatibility, not necessarily for performance or ease of use.
The dictionary is almost universally available because it was introduced in WSH 2.0. Dictionaries might even be more compatible than VBScript arrays if your scripts will be used in a tool that includes non-VBScript components. A dictionary can be used and manipulated by any language that understands COM, something that isn't guaranteed for VBScript arrays.
You don't lose anything by using a dictionary instead of a VBScript array. There are useful VBScript functions that work only with arrays, notably Join and Filter, but you can turn a dictionary into an array in one step as demonstrated in Listings 3 and 4.
Ironically, dictionaries also win in the performance department. We expect tools that are internal to VBScript such as dynamic arrays to be significantly faster than external tools such as the dictionary. Creating a dictionary does take much longer than creating a dynamic array—milliseconds instead of microseconds. After that, a very peculiar thing happens. We see similar performance when adding elements to either a dynamic array or a dictionary at first, but as the array grows, it slows down because dynamic arrays are fakes. When we redimension an array containing data that you need to keep, VBScript creates a brand new array and copies each entry to it. As a result, resizing an array from 1000 to 1001 elements takes approximately 100 times as much work as resizing it from 10 to 11 elements. There are ways to work around this dynamic array problem, but they increase code complexity and don't solve the fundamental problem of nonlinear performance.
Dictionaries are really second-generation arrays. As such, they resolve many of the historic problems of earlier array structures and present arrays as objects rather than as a set of internal language hacks. If you're dissatisfied with VBScript's dynamic arrays, dictionaries are the logical next step.