14.5. Accessing Collections with Indices

Any collection can generate an Index that can be used to access its members. The command to create an Index for a given collection is begin:. The type of Index created by a collection depends on the type of collection being indexed. If one desires an index of randomly shuffled members of a collection, then beginPermuted: is the necessary command.

An Index object will understand messages like get, which will return the object at which the Index is currently positioned, next, which will move the Index object to the next object in the collection and return that object, and findNext: objectName, which will cause the Index object to search forward into the collection until it finds an object that is the same as objectName.

The usage of indexes can make some code work more smoothly. For example, as we noted in our discussion of Lists, the Index can be used to orchestrate the repetitive processing of a List object in the following way:

id aCollection;
id <Index> index;
aCollection = [List create: [self getZone]];
index =  [aCollection begin: [self getZone]];5

while( (anObject=[index next]) != nil )
  //write code that does something to anObject

This code will cycle through the List. Because the Index object remembers its position in the List, the processing is efficient in the sense that the next command causes just one step to be taken. This is a sharp contrast with the usage of collections methods like [aCollection atOffset: i], which cause the List to begin at the beginning and count up to the ith object.

Perhaps the most significant advantage of indices is that they can be used manage collections. If items are removed from a collection by its Index object, then the Index object is automatically kept up to date. On the other hand, if items are removed directly by collections methods, such as [aCollection remove: thisObject], then the indexes that had been previously created for that List will be damaged and they must be dropped and recreated. On the other hand, if an Index is positioned on the desired member, and then the index is told to remove that object, then the change will be made in the collection and the index will automatically be adjusted.

In order to make an index remove objects correctly, the fundamental problem is to correctly position the index within the collection. To make an index object reposition itself at the beginning of the collection, the command [index setLoc: Start] can be used. Index objects can be manually positioned with methods like [index findNext: targetObject] or [setOffset: i]. These will, respectively, move to the next object which, according to the comparison function, matches the target object, or move the index to the ith object in the collection. Once the index is positioned, then the object can be removed with [index remove].

The Swarm List class creates Index objects that have more functionality than the other classes. The Index of a List class collection can be used to insert objects as well as delete them. For example, [index addAfter: newObject] can set a new object into a collection after the object currently under the index. The addition of objects by the index is not allowed in Swarm Arrays or Maps because of the internal structure of those classes.