Portable Object Compiler (c) 1997,98,2003.  All Rights Reserved.

SortCltn

Inherits from: Cltn

Class Description

SortCltn (alias SortedCollection) instances are groups of objects that are kept in sorted order in a tree (by default, the first object is the smallest with respect to compare:).  Inserting and searching objects in such a sorted collection can be faster than using, say an OrdCltn object collection.

Creating An Instance

The method new creates an instance that sorts its elements with respect to compare:.  The method newDictCompare sends dictCompare: messages to compare pairs of elements.  Finally, the method sortBy:: creates a SortCltn that will sort its contents with respect to an arbitrary Block.

Adding Objects

Normally, you insert an object with the add: method.  This method allows you to add an object to the collection, even when it is equal to an element in the collection (when the comparison method returns zero; because you can use a different method than compare:, this doesn't necessarily mean that isEqual: returns YES).

You can also choose not to add duplicate entries.  The addNTest: method adds if the object was absent and returns a value that can be used to test whether the object was found or not. The filter: method frees a new entry when it's a duplicate.  The replace: method always replaces duplicates (returning the object that was previously in the collection).

Sorting collections 

One use of SortCltn instances, is to sort collections of objects.  For example,

aSortCltn = [[SortCltn new] addAll:aCltn];

will sequence of the contents of aCltn and will add the members of the collection to a new SortCltn instance.  This is equivalent to sorting the collection.  To obtain a sorted OrdCltn instance (as opposed to a SortCltn), simply convert back like this,

aCltn = [[OrdCltn new] addAll:aSortCltn];

To filter out duplicate entries, it's also possible to insert a Set instance in the conversion process.

Method types

Creation	- new
	- new:
	- newDictCompare
	- sortBy:
	- sortBlock:
	- newCmpSel:
	- with:
	- with:with:
	- add:
	- copy
	- deepCopy
	- emptyYourself
	- freeContents
	- free

Interrogation	- size
	- isEmpty
	- eachElement

Comparing	- hash
	- isEqual:

Adding	- add:
	- addNTest:
	- filter:
	- replace:

Removing	- remove:

Testing Contents	- includesAllOf:
	- includesAnyOf:

Adding and Removing Contents	- addAll:
	- addContentsOf:
	- addContentsTo:
	- removeAll:
	- removeContentsFrom:
	- removeContentsOf:

Combining	- intersection:
	- union:
	- difference:

Converting	- asSet
	- asOrdCltn

Using Blocks	- detect:
	- detect:ifNone:
	- select:
	- reject:
	- collect:
	- count:

Making elements perform	- elementsPerform:
	- elementsPerform:with:
	- elementsPerform:with:with:
	- elementsPerform:with:with:with:

Do Blocks	- do:
	- do:until:

Locating	- find:
	- contains:

Printing	- printOn:

Archiving	- fileOutOn:
	- fileInFrom:

Methods

new
+new

Returns a new instance that sorts its contents with respect to compare:.

new:
+new:(unsigned)n

For this class, this method does not differ from new.

newDictCompare
+newDictCompare

Returns a new instance that sorts its contents with respect to dictCompare:.

sortBy:
+sortBy:sortBlock

Returns a new instance that sorts its contents with respect to sortBlock.  This block should take two objects a and b as argument, and return a positive value if a is greater than b, or zero if a and b are equal, and a negative value if a is less than b.

id c;
int r;
c = [SortCltn sortBy:{ :a:b | [a compare:b] }];

sortBlock:
+sortBlock:sortBlock

Same as sortBy:.

Note: There is a SortedCollection method with a similar name in Squeak.

newCmpSel:
+newCmpSel:(SEL)aSel

For backwards compatibility only.  sortBy: provides a more powerful mechanism to sort given an arbitrary sort block.

with:
+with:(int)nArgs,...

Returns a new object with nArgs elements.  For example,

id aCltn = [OrdCltn with:2,anObject,otherObject];

creates a collection and adds anObject and otherObject to it.  In a similar way, Set or SortCltn instances can be created like this.

with:with:
+with:firstObjectwith:nextObject

This method is equivalent to with: 2,firstObject,nextObject. 

add:
+add:firstObject

This method is equivalent to with: 1,firstObject. 

This (factory) method has the same name as the instance method add: and can be used as follows, in circumstances when the user does not want to allocate a collection unless it is actually used :

aCltn = [ (aCltn)?aCltn:OrdCltn add:myObject ];

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 add:.

copy
-copy

Returns a new copy of the object (without copying the elements).

deepCopy
-deepCopy

Returns a new copy of the object.  The elements in the new copy are deep copies of the elements in the original object.

emptyYourself
-emptyYourself

Empties all the members of the object (without freeing them).  Returns the receiver.

freeContents
-freeContents

Removes and frees the contents of the object, but doesn't free the object itself.  Returns the receiver.

free
-free

Frees the object, but not its contents.  Returns nil.  Do :

aSort = [[aSort freeContents] free];

if you want to free the object and its contents.

size
- (unsigned)size

Returns the number of elements in the object.

isEmpty
- (BOOL)isEmpty

Whether the number of elements is equal to zero.

eachElement
-eachElement

Returns a sequence of sorted elements.  The first element in the sequence is the smallest with respect to the ordering.

aSeq = [aSort eachElement];
while ((anElement = [aSeq next])) {
    /* do something */
}
aSeq = [aSeq free];

hash
- (unsigned)hash

Returns a hash value based on the receiver's address and the results of sending the hash message to the contents.

isEqual:
- (BOOL)isEqual:aSort

Returns YES if aSort is an SortCltn instance, and if each member of its contents responds affirmatively to the message isEqual: when compared to the corresponding member of the receiver's contents.

add:
-add:anObject

Adds anObject to the receiver, keeping the contents of the object sorted.  Duplicate entries are allowed.  Returns the receiver.

addNTest:
-addNTest:anObject

Adds anObject if it was not previously in the set.  Returns anObject if the addition takes place, otherwise returns nil.

filter:
-filter:anObject

If anObject compares equally to some object in the contents of the receiver, then anObject is freed, and the matching object is returned.  Otherwise, anObject is added and returned.

replace:
-replace:anObject

If a matching object is found, then anObject replaces that object, and the matching object is returned.  If there is no matching object, anObject is added to the receiver, and nil is returned.

remove:
-remove:oldObject

Removes oldObject or the element that matches (when the compare method returns zero).  Returns the removed entry, or nil if there is no matching entry.

Note: Not implemented

includesAllOf:
- (BOOL)includesAllOf:aCltn

Answer whether all the elements of aCltn are in the receiver, by sending includes: for each individual element.

includesAnyOf:
- (BOOL)includesAnyOf:aCltn

Answer whether any element of aCltn is in the receiver, by sending includes: for each individual element.

addAll:
-addAll:aCltn

Adds each member of aCltn to the receiver.  If aCltn is nil, no action is taken.  The argument aCltn need not be a collection, so long as it responds to eachElement in the same way as collections do.  Returns the receiver.

Note: If aCltn is the same object as the receiver, a addYourself message is sent to the object.

addContentsOf:
-addContentsOf:aCltn

This method is equivalent to addAll: and is provided for Stepstone ICpak101 compatibility.

addContentsTo:
-addContentsTo:aCltn

This method is equivalent to addAll:, but with argument and receiver interchanged, and is provided for Stepstone ICpak101 compatibility.

removeAll:
-removeAll:aCltn

Removes all of the members of aCltn from the receiver. The argument aCltn need not be a collection, as long as it responds to eachElement as collections do.  Returns the receiver. 

Note: If aCltn is the same object as the receiver, it empties itself using emptyYourself and returns the receiver.

removeContentsFrom:
-removeContentsFrom:aCltn

This method is equivalent to removeAll:, and is provided for compatibility with Stepstone ICpak101.

removeContentsOf:
-removeContentsOf:aCltn

This method is equivalent to removeAll:, and is provided for compatibility with Stepstone ICpak101.

intersection:
-intersection:bag

Returns a new Collection which is the intersection of the receiver and bag.  The new Collection contains only those elements that were in both the receiver and bag.  The argument bag need not be an actual Set or Bag instance, as long as it implements find: as Sets do.

union:
-union:bag

Returns a new Collection which is the union of the receiver and bag.  The new Collection returned has all the elements from both the receiver and bag.  The argument bag need not be an actual Set or Bag instance, as long as it implements eachElement: as Sets and Bags do.

difference:
-difference:bag

Returns a new Collection which is the difference of the receiver and bag.  The new Collection returned has only those elements in the receiver that are not in bag.

asSet
-asSet

Creates a Set instance and adds the contents of the object to the set.

asOrdCltn
-asOrdCltn

Creates a OrdCltn instance and adds the contents of the object to the set.

detect:
-detect:aBlock

This message returns the first element in the receiver for which aBlock evaluates to something that is non-nil .  For example, the following :

[ aCltn detect: { :each | [each isEqual:anObject] } ];

Returns nil if there's no element for which aBlock evaluates to something that non-nil.

detect:ifNone:
-detect:aBlockifNone:noneBlock

This message returns the first element in the receiver for which aBlock evaluates to something that is non-nil.

Evaluates noneBlock if there's no element for which aBlock evaluates to something that is non-nil, and returns the return value of that block.  For example,

[ aCltn detect: { :e | [e isEqual:anObject]} ifNone: {anObject} ];

select:
-select:testBlock

This message will return a subset of the receiver containing all elements for which testBlock evaluates to an Object that is non-nil.  For example,

[ aCltn select: { :each | [each isEqual:anObject] } ];

Returns a new empty instance of the same class as the receiver, if there's no element for which testBlock evaluates to something that is non-nil. 

reject:
-reject:testBlock

Complement of select:

This message will return a subset of the receiver containing all elements for which testBlock evaluates to nil.  For example,

[ aCltn reject: { :each | [each isEqual:anObject] } ];

Returns a new empty instance of the same class as the receiver, if there's no element for which testBlock evaluates to nil.

collect:
-collect:transformBlock

This message creates and returns a new collection of the same size and type as the receiver. The elements are the result of performing transformBlock on each element in the receiver (elements for which the Block would return nil are filtered out).

count:
- (unsigned)count:aBlock

Evaluate aBlock with each of the receiver's elements as the argument.  Return the number that answered a non-nil value.

elementsPerform:
-elementsPerform:(SEL)aSelector

Send aSelector to all objects in the collection, starting from the object at offset 0.  For Stepstone compatibility.  Producer uses this.

elementsPerform:with:
-elementsPerform:(SEL)aSelectorwith:anObject

Send aSelector to all objects in the collection, starting from the object at offset 0.  For Stepstone compatibility.  Producer uses this.

elementsPerform:with:with:
-elementsPerform:(SEL)aSelectorwith:anObjectwith:otherObject

Send aSelector to all objects in the collection, starting from the object at offset 0.  For Stepstone compatibility.  Producer uses this.

elementsPerform:with:with:with:
-elementsPerform:(SEL)aSelectorwith:anObjectwith:otherObjectwith:thirdObj

Send aSelector to all objects in the collection, starting from the object at offset 0.  For Stepstone compatibility.  ICpak201 uses this.

do:
-do:aBlock

Evaluates aBlock for each element in the collection and returns self.  aBlock must be a block taking one object (element) as argument; the return value of the block is ignored by this method.

Often, the Block would, as a side-effect, modify a variable, as in:

int count = 0;
[contents do: { :what | if (what == anObject) count++; }];

do:until:
-do:aBlockuntil:(BOOL*)flag

Evaluates aBlock for each element in the collection, or until the variable pointed to by flag becomes true, and returns self.  aBlock must be a block taking one object (element) as argument; the return value of the block is ignored by this method.

Typically the Block will modify the variable flag when some condition holds:

BOOL found = NO;
[contents do:{ :what | if (what == findObject) found=YES;} until:&found];
if (found) { ... }

find:
-find:anObject

Returns any element in the receiver which isEqual: to anObject.  Otherwise, returns nil.

contains:
- (BOOL)contains:anObject

Returns YES if the receiver contains anObject.  Otherwise, returns NO.  Implementation is in terms of the receiver's find: method.

printOn:
-printOn:(IOD)aFile

Prints a comma separated list of the objects in the set by sending each individual object a printOn: message.  Returns the receiver.

fileOutOn:
-fileOutOn:aFiler

Writes the tree and all its elements to aFiler.  Returns the receiver.

fileInFrom:
-fileInFrom:aFiler

Reads the tree and all its elements from aFiler.  Returns the receiver.