.TH "set" 3 "Oct 12, 2003" .SH Set .PP .B Inherits from: Cltn .SH Class Description .PP .B Set instances are sets of objects with no duplicate (in the sense of .B isEqual: ) entries\&. The .B Dictionary class provides a key-value based interface to sets, and may sometimes be more convenient to use\&. .PP To make Sets correctly work, the objects have to implement a pair of comparison methods which must act in a coordinated way : .PP The message .RS 3 [newElement isEqual:oldElement] .br .RE .PP is expected to report whether .I newElement is equal to .I oldElement \&. .PP The message .RS 3 [newElement hash] .br .RE .PP should return an integer which is equal for all objects for which .B isEqual: is true\&. .PP Sets place all objects added to them into a hash table based on the results of sending the objects the .B hash message\&. .B Set assumes that, after being added to a set, objects, and their hash value, will not be changed\&. If any object does change, it will not be located properly in the set\&. The result of this is that the object will not be found or that it will be added to the set more than once\&. .SH Adding Objects .PP The methods .B add: , .B addNTest: , .B filter: , .B replace: and .B add:ifDuplicate: are used to add objects to a set\&. The difference between these methods is the procedure used in adding, how duplicates are handled and what value is returned\&. .SH Method types .PP .B Creation .RS 3 .br * new .br * new: .br * with: .br * with:with: .br * add: .br * copy .br * deepCopy .br * emptyYourself .br * freeContents .br * free .RE .PP .B Interrogation .RS 3 .br * size .br * isEmpty .br * eachElement .RE .PP .B Comparing .RS 3 .br * isEqual: .RE .PP .B Adding .RS 3 .br * add: .br * addNTest: .br * filter: .br * add:ifDuplicate: .br * replace: .RE .PP .B Removing .RS 3 .br * remove: .br * remove:ifAbsent: .RE .PP .B Testing Contents .RS 3 .br * includesAllOf: .br * includesAnyOf: .RE .PP .B Adding and Removing Contents .RS 3 .br * addAll: .br * addContentsOf: .br * addContentsTo: .br * removeAll: .br * removeContentsFrom: .br * removeContentsOf: .RE .PP .B Combining .RS 3 .br * intersection: .br * union: .br * difference: .RE .PP .B Converting .RS 3 .br * asSet .br * asOrdCltn .RE .PP .B Using Blocks .RS 3 .br * detect: .br * detect:ifNone: .br * select: .br * reject: .br * collect: .br * count: .RE .PP .B Making elements perform .RS 3 .br * elementsPerform: .br * elementsPerform:with: .br * elementsPerform:with:with: .br * elementsPerform:with:with:with: .RE .PP .B Do Blocks .RS 3 .br * do: .br * do:until: .RE .PP .B Locating .RS 3 .br * find: .br * contains: .br * includes: .br * occurrencesOf: .RE .PP .B Printing .RS 3 .br * printOn: .RE .PP .B Archiving .RS 3 .br * fileOutOn: .br * fileInFrom: .br * awakeFrom: .RE .SH Methods .PP new .RS 1 + .B new .RE .PP Returns a new empty set\&. .PP new: .RS 1 + .B new :(unsigned) .I n .RE .PP Returns a new empty set, which can hold at least .I n elements\&. .PP with: .RS 1 + .B with :(int) .I nArgs,\&.\&.\&. .RE .PP Returns a new object with .I nArgs elements\&. For example, .RS 3 id aCltn = [OrdCltn with:2,anObject,otherObject]; .br .RE .PP creates a collection and adds .I anObject and .I otherObject to it\&. In a similar way, .B Set or .B SortCltn instances can be created like this\&. .PP with:with: .RS 1 + .B with : .I firstObject .B with : .I nextObject .RE .PP This method is equivalent to .B with: 2, .I firstObject , .I nextObject \&. .PP add: .RS 1 + .B add : .I firstObject .RE .PP This method is equivalent to .B with: 1, .I firstObject \&. .PP This (factory) method has the same name as the instance method .B add: and can be used as follows, in circumstances when the user does not want to allocate a collection unless it is actually used : .RS 3 aCltn = [ (aCltn)?aCltn:OrdCltn add:myObject ]; .br .RE .PP This shows that creation of the collection is delayed until it is actually needed\&. If the collection already exists, objects are simply added, using the instance method .B add: \&. .PP copy .RS 1 - .B copy .RE .PP Returns a new copy of the set\&. .PP deepCopy .RS 1 - .B deepCopy .RE .PP Returns a new copy of the set\&. The elements in the new set are deep copies of the elements in the original set\&. .PP emptyYourself .RS 1 - .B emptyYourself .RE .PP Empties all the members of the set (without freeing them)\&. Returns the receiver\&. .PP freeContents .RS 1 - .B freeContents .RE .PP Removes and frees all the members of the set, but doesn\&'t free the set itself\&. Returns the receiver\&. .PP free .RS 1 - .B free .RE .PP Frees the set, but not its elements\&. Returns .B nil \&. Do : .RS 3 set = [[set freeContents] free]; .br .RE .PP if you want to free the set and its contents\&. .PP size .RS 1 - ( unsigned ) .B size .RE .PP Returns the number of elements in the set\&. .PP isEmpty .RS 1 - ( BOOL ) .B isEmpty .RE .PP Whether the number of objects in the set is equal to zero\&. .PP eachElement .RS 1 - .B eachElement .RE .PP Returns a sequence of elements in the set\&. .RS 3 seq = [set eachElement]; .br while ((anElement = [aSeq next])) { .br /* do something */ .br } .br aSeq = [aSeq free]; .br .RE .PP isEqual: .RS 1 - ( BOOL ) .B isEqual : .I set .RE .PP Returns YES if .I set is a set, if .I set has the same number of elements as the receiver, and if each member of the contents of .I set is contained in the receiver\&'s contents\&. .PP add: .RS 1 - .B add : .I anObject .RE .PP Adds .I anObject if it was not previously in the set, but doesn\&'t inform the caller about the addition because the receiver is always returned\&. .PP addNTest: .RS 1 - .B addNTest : .I anObject .RE .PP Adds .I anObject if it was not previously in the set\&. Returns .I anObject if the addition takes place, otherwise returns .B nil \&. .PP filter: .RS 1 - .B filter : .I anObject .RE .PP The .B filter: method has a special purpose\&. If there is a matching object in the set, then .I anObject is freed, and the matching object is returned\&. Otherwise, .I anObject is added and returned\&. .PP add:ifDuplicate: .RS 1 - .B add : .I anObject .B ifDuplicate : .I aBlock .RE .PP Adds and returns .I anObject , if there was no duplicate previously in the set\&. .PP Otherwise, this method evalutes .I aBlock and returns the matching object (the object that was already in the set)\&. .PP For example, the .B filter: method is equivalent to : .RS 3 [ set add: anObject ifDuplicate: { [anObject free] }]; .br .RE .PP replace: .RS 1 - .B replace : .I anObject .RE .PP If a matching object is found, then .I anObject replaces that object, and the matching object is returned\&. If there is no matching object, .I anObject is added to the receiver, and .B nil is returned\&. .PP remove: .RS 1 - .B remove : .I oldObject .RE .PP Removes .I oldObject or the element which matches it using .B isEqual: \&. Returns the removed entry, or .B nil if there is no matching entry\&. .PP .B Note: The .B remove: method of the .B OrdCltn class is implemented to remove an exact match\&. The .B Set class uses a match in the sense of .B isEqual: instead\&. .PP remove:ifAbsent: .RS 1 - .B remove : .I oldObject .B ifAbsent : .I exceptionBlock .RE .PP Removes .I oldObject or the element which matches it using .B isEqual: \&. Returns the removed entry, or return value of .I exceptionBlock if there is no matching entry\&. .PP For example, the method .B remove: is equivalent to : .RS 3 [ set remove: oldObject ifAbsent: { nil } ]; .br .RE .PP .B Note: The .B remove: method of the .B OrdCltn class is implemented to remove an exact match\&. The .B Set class uses a match in the sense of .B isEqual: instead\&. .PP includesAllOf: .RS 1 - ( BOOL ) .B includesAllOf : .I aCltn .RE .PP Answer whether all the elements of .I aCltn are in the receiver, by sending .B includes: for each individual element\&. .PP includesAnyOf: .RS 1 - ( BOOL ) .B includesAnyOf : .I aCltn .RE .PP Answer whether any element of .I aCltn is in the receiver, by sending .B includes: for each individual element\&. .PP addAll: .RS 1 - .B addAll : .I aCltn .RE .PP Adds each member of .I aCltn to the receiver\&. If .I aCltn is .B nil , no action is taken\&. The argument .I aCltn need not be a collection, so long as it responds to .B eachElement in the same way as collections do\&. Returns the receiver\&. .PP .B Note: If .I aCltn is the same object as the receiver, a .B addYourself message is sent to the object\&. .PP addContentsOf: .RS 1 - .B addContentsOf : .I aCltn .RE .PP This method is equivalent to .B addAll: and is provided for Stepstone ICpak101 compatibility\&. .PP addContentsTo: .RS 1 - .B addContentsTo : .I aCltn .RE .PP This method is equivalent to .B addAll: , but with argument and receiver interchanged, and is provided for Stepstone ICpak101 compatibility\&. .PP removeAll: .RS 1 - .B removeAll : .I aCltn .RE .PP Removes all of the members of .I aCltn from the receiver\&. The argument .I aCltn need not be a collection, as long as it responds to .B eachElement as collections do\&. Returns the receiver\&. .PP .B Note: If .I aCltn is the same object as the receiver, it empties itself using .B emptyYourself and returns the receiver\&. .PP removeContentsFrom: .RS 1 - .B removeContentsFrom : .I aCltn .RE .PP This method is equivalent to .B removeAll: , and is provided for compatibility with Stepstone ICpak101\&. .PP removeContentsOf: .RS 1 - .B removeContentsOf : .I aCltn .RE .PP This method is equivalent to .B removeAll: , and is provided for compatibility with Stepstone ICpak101\&. .PP intersection: .RS 1 - .B intersection : .I bag .RE .PP Returns a new Collection which is the intersection of the receiver and .I bag \&. The new Collection contains only those elements that were in both the receiver and .I bag \&. The argument .I bag need not be an actual .B Set or .B Bag instance, as long as it implements .B find: as Sets do\&. .PP union: .RS 1 - .B union : .I bag .RE .PP Returns a new Collection which is the union of the receiver and .I bag \&. The new Collection returned has all the elements from both the receiver and .I bag \&. The argument .I bag need not be an actual .B Set or .B Bag instance, as long as it implements .B eachElement: as Sets and Bags do\&. .PP difference: .RS 1 - .B difference : .I bag .RE .PP Returns a new Collection which is the difference of the receiver and .I bag \&. The new Collection returned has only those elements in the receiver that are not in .I bag \&. .PP asSet .RS 1 - .B asSet .RE .PP Creates a .B Set instance and adds the contents of the object to the set\&. .PP asOrdCltn .RS 1 - .B asOrdCltn .RE .PP Creates a .B OrdCltn instance and adds the contents of the object to the set\&. .PP detect: .RS 1 - .B detect : .I aBlock .RE .PP This message returns the first element in the receiver for which .I aBlock evaluates to something that is non-nil \&. For example, the following : .RS 3 [ aCltn detect: { :each | [each isEqual:anObject] } ]; .br .RE .PP Returns .B nil if there\&'s no element for which .I aBlock evaluates to something that non-nil\&. .PP detect:ifNone: .RS 1 - .B detect : .I aBlock .B ifNone : .I noneBlock .RE .PP This message returns the first element in the receiver for which .I aBlock evaluates to something that is non-nil\&. .PP Evaluates .I noneBlock if there\&'s no element for which .I aBlock evaluates to something that is non-nil, and returns the return value of that block\&. For example, .RS 3 [ aCltn detect: { :e | [e isEqual:anObject]} ifNone: {anObject} ]; .br .RE .PP select: .RS 1 - .B select : .I testBlock .RE .PP This message will return a subset of the receiver containing all elements for which .I testBlock evaluates to an Object that is non-nil\&. For example, .RS 3 [ aCltn select: { :each | [each isEqual:anObject] } ]; .br .RE .PP Returns a new empty instance of the same class as the receiver, if there\&'s no element for which .I testBlock evaluates to something that is non-nil\&. .PP reject: .RS 1 - .B reject : .I testBlock .RE .PP Complement of .B select: .PP This message will return a subset of the receiver containing all elements for which .I testBlock evaluates to nil\&. For example, .RS 3 [ aCltn reject: { :each | [each isEqual:anObject] } ]; .br .RE .PP Returns a new empty instance of the same class as the receiver, if there\&'s no element for which .I testBlock evaluates to nil\&. .PP collect: .RS 1 - .B collect : .I transformBlock .RE .PP This message creates and returns a new collection of the same size and type as the receiver\&. The elements are the result of performing .I transformBlock on each element in the receiver (elements for which the Block would return .B nil are filtered out)\&. .PP count: .RS 1 - ( unsigned ) .B count : .I aBlock .RE .PP Evaluate .I aBlock with each of the receiver\&'s elements as the argument\&. Return the number that answered a non- .B nil value\&. .PP elementsPerform: .RS 1 - .B elementsPerform :(SEL) .I aSelector .RE .PP Send .I aSelector to all objects in the collection, starting from the object at offset .I 0 \&. For Stepstone compatibility\&. Producer uses this\&. .PP elementsPerform:with: .RS 1 - .B elementsPerform :(SEL) .I aSelector .B with : .I anObject .RE .PP Send .I aSelector to all objects in the collection, starting from the object at offset .I 0 \&. For Stepstone compatibility\&. Producer uses this\&. .PP elementsPerform:with:with: .RS 1 - .B elementsPerform :(SEL) .I aSelector .B with : .I anObject .B with : .I otherObject .RE .PP Send .I aSelector to all objects in the collection, starting from the object at offset .I 0 \&. For Stepstone compatibility\&. Producer uses this\&. .PP elementsPerform:with:with:with: .RS 1 - .B elementsPerform :(SEL) .I aSelector .B with : .I anObject .B with : .I otherObject .B with : .I thirdObj .RE .PP Send .I aSelector to all objects in the collection, starting from the object at offset .I 0 \&. For Stepstone compatibility\&. ICpak201 uses this\&. .PP do: .RS 1 - .B do : .I aBlock .RE .PP Evaluates .I aBlock for each element in the collection and returns .B self \&. .I aBlock must be a block taking one object (element) as argument; the return value of the block is ignored by this method\&. .PP Often, the Block would, as a side-effect, modify a variable, as in: .RS 3 int count = 0; .br [contents do: { :what | if (what == anObject) count++; }]; .br .RE .PP do:until: .RS 1 - .B do : .I aBlock .B until :(BOOL*) .I flag .RE .PP Evaluates .I aBlock for each element in the collection, or until the variable pointed to by .I flag becomes true, and returns .B self \&. .I aBlock must be a block taking one object (element) as argument; the return value of the block is ignored by this method\&. .PP Typically the Block will modify the variable .I flag when some condition holds: .RS 3 BOOL found = NO; .br [contents do:{ :what | if (what == findObject) found=YES;} until:&found]; .br if (found) { \&.\&.\&. } .br .RE .PP find: .RS 1 - .B find : .I anObject .RE .PP Returns any element in the receiver which .B isEqual: to .I anObject \&. Otherwise, returns .B nil \&. .PP contains: .RS 1 - ( BOOL ) .B contains : .I anObject .RE .PP Returns YES if the receiver contains .I anObject \&. Otherwise, returns NO\&. Implementation is in terms of the receiver\&'s .B find: method (which uses .B isEqual: and .B hash to decide whether the object is contained in the set)\&. .PP includes: .RS 1 - ( BOOL ) .B includes : .I anObject .RE .PP This method is equivalent to .B contains: \&. .PP occurrencesOf: .RS 1 - ( unsigned ) .B occurrencesOf : .I anObject .RE .PP Returns 1 if .I anObject is in the receiver, otherwise returns 0\&. Implementation is in terms of the receiver\&'s .B find: method (which uses .B isEqual: and .B hash )\&. .PP printOn: .RS 1 - .B printOn :(IOD) .I aFile .RE .PP Prints a list of the objects in the set by sending each individual object a .B printOn: message\&. Returns the receiver\&. .PP fileOutOn: .RS 1 - .B fileOutOn : .I aFiler .RE .PP Writes out non-nil objects in the Set on .I aFiler \&. Returns the receiver\&. .PP fileInFrom: .RS 1 - .B fileInFrom : .I aFiler .RE .PP Reads in objects from .I aFiler \&. Returns the receiver, which is a set that is not yet usable (until the set gets the .B awakeFrom: message)\&. .PP awakeFrom: .RS 1 - .B awakeFrom : .I aFiler .RE .PP Rehashes the contents of the set, which was previously read from .I aFiler by the .I fileInFrom: method\&. The hash-values of the objects are possibly process or architecture dependent, so they are not stored on the filer\&. Rather, .B awakeFrom: recomputes the values\&.