Collections-Unordered

Bag
I represent an unordered collection of possibly duplicate elements.

I store these elements in a dictionary, tallying up occurrences of equal objects. Because I store an occurrence only once, my clients should beware that objects they store will not necessarily be retrieved such that == is true. If the client cares, a subclass of me should be created.
=
Two bags are equal if
(a) they are the same 'kind' of thing.
(b) they have the same size.
(c) each element occurs the same number of times in both of them
add:
Include newObject as one of the receiver's elements. Answer newObject.
add:withOccurrences:
Add newObject anInteger times to the receiver. Answer newObject.
asBag
Answer a Bag whose elements are the elements of the receiver.
asSet
Answer a set with the elements of the receiver.
at:
Primitive. Assumes receiver is indexable. Answer the value of an
indexable element in the receiver. Fail if the argument index is not an
Integer or is out of bounds. Essential. See Object documentation
whatIsAPrimitive.
at:put:
Primitive. Assumes receiver is indexable. Store the argument value in
the indexable element of the receiver indicated by index. Fail if the
index is not an Integer or is out of bounds. Or fail if the value is not of
the right type for this kind of collection. Answer the value that was
stored. Essential. See Object documentation whatIsAPrimitive.
contentsClass
copy
Answer another instance just like the receiver. Subclasses typically override postCopy; they typically do not override shallowCopy.
cumulativeCounts
Answer with a collection of cumulative percents covered by elements so far.
do:
Refer to the comment in Collection|do:.
includes:
Refer to the comment in Collection|includes:.
new
new:
newFrom:
occurrencesOf:
Refer to the comment in Collection|occurrencesOf:.
remove:ifAbsent:
Refer to the comment in Collection|remove:ifAbsent:.
removeAll
Implementation Note: as contents will be overwritten, a shallowCopy of self would be modified.
An alternative implementation preserving capacity would be to create a new contents:
self setContents: (self class contentsClass new: contents size).
setContents:
size
Answer how many elements the receiver contains.
snapshotCopy
sortedCounts
Answer with a collection of counts with elements, sorted by decreasing
count.
sortedElements
Answer with a collection of elements with counts, sorted by element.
valuesAndCounts
Dictionary
I represent a set of elements that can be viewed from one of two perspectives: a set of associations, or a container of values that are externally named where the name can be any object that responds to =. The external name is referred to as the key. I inherit many operations from Set.
=
Two dictionaries are equal if
(a) they are the same 'kind' of thing.
(b) they have the same set of keys.
(c) for each (common) key, they have the same value
add:
Include newObject as one of the receiver's elements, but only if
not already present. Answer newObject.
addAll:
Include all the elements of aCollection as the receiver's elements. Answer
aCollection. Actually, any object responding to #do: can be used as argument.
associationAt:
associationAt:ifAbsent:
Answer the association with the given key.
If key is not found, return the result of evaluating aBlock.
associationDeclareAt:
Return an existing association, or create and return a new one. Needed as a single message by ImageSegment.prepareToBeSaved.
associations
Answer a Collection containing the receiver's associations.
associationsDo:
Evaluate aBlock for each of the receiver's elements (key/value
associations).
associationsSelect:
Evaluate aBlock with each of my associations as the argument. Collect
into a new dictionary, only those associations for which aBlock evaluates
to true.
at:
Answer the value associated with the key.
at:ifAbsent:
Answer the value associated with the key or, if key isn't found,
answer the result of evaluating aBlock.
at:ifAbsentPut:
Return the value at the given key.
If key is not included in the receiver store the result
of evaluating aBlock as new value.
at:ifPresent:
Lookup the given key in the receiver. If it is present, answer the value of evaluating the given block with the value associated with the key. Otherwise, answer nil.
at:ifPresentAndInMemory:
Lookup the given key in the receiver. If it is present, answer the value of evaluating the given block with the value associated with the key. Otherwise, answer nil.
at:put:
Set the value at key to be anObject. If key is not found, create a
new entry for key and set is value to anObject. Answer anObject.
bindingOf:
bindingsDo:
collect:
Evaluate aBlock with each of my values as the argument. Collect the
resulting values into a collection that is like me. Answer with the new
collection.
collect:displayingProgress:
Evaluate aBlock with each of my values as the argument. Collect the
resulting values into a collection that is like me. Answer with the new
collection.
copy
Must copy the associations, or later store will affect both the
original and the copy
customizeExplorerContents
declare:from:
Add key to the receiver. If key already exists, do nothing. If aDictionary
includes key, then remove it from aDictionary and use its association as
the element of the receiver.
do:
Evaluate aBlock with each of the receiver's elements as the argument.
errorKeyNotFound
errorValueNotFound
explorerContentsWithIndexCollect:
flattenOnStream:
hasBindingThatBeginsWith:
Answer true if the receiver has a key that begins with aString, false otherwise
includes:
Answer whether anObject is one of the receiver's elements.
includesAssociation:
includesIdentity:
Answer whether anObject is one of the values of the receiver. Contrast #includes: in which there is only an equality check, here there is an identity check
includesKey:
Answer whether the receiver has a key equal to the argument, key.
inspectorClass
Answer the class of the inspector to be used on the receiver. Called by inspect;
use basicInspect to get a normal (less useful) type of inspector.
inspectorFields
isDictionary
javascriptOn:
keyAt:
May be overridden by subclasses so that fixCollisions will work
keyAtIdentityValue:
Answer the key that is the external name for the argument, value. If
there is none, answer nil.
Note: There can be multiple keys with the same value. Only one is returned.
keyAtIdentityValue:ifAbsent:
Answer the key that is the external name for the argument, value. If
there is none, answer the result of evaluating exceptionBlock.
Note: There can be multiple keys with the same value. Only one is returned.
keyAtValue:
Answer the key that is the external name for the argument, value. If
there is none, signal an error.
keyAtValue:ifAbsent:
Answer the key that is the external name for the argument, value. If
there is none, answer the result of evaluating exceptionBlock.
: Use =, not ==, so stings like 'this' can be found. Note that MethodDictionary continues to use == so it will be fast.
keyForIdentity:
If anObject is one of the values of the receive, return its key, else return nil. Contrast #keyAtValue: in which there is only an equality check, here there is an identity check
keys
Answer a Set containing the receiver's keys.
keysAndValuesDo:
keysAndValuesRemove:
Removes all entries for which keyValueBlock returns true.
keysDo:
Evaluate aBlock for each of the receiver's keys.
keysSortedSafely
Answer a SortedCollection containing the receiver's keys.
newFrom:
newFromPairs:
niAddNewEntry
niChildrenBlockForIndexedFields
niConfiguration
niDescription
niNodeBlockForIndexedFields
noCheckAdd:
Must be defined separately for Dictionary because (self findElementOrNil:) expects a key, not an association. 9/7/96 tk
occurrencesOf:
Answer how many of the receiver's elements are equal to anObject.
printElementsOn:
The original code used #skip:, but some streams do not support that,
and we don't really need it.
rehash
Smalltalk rehash.
remove:
Remove oldObject from the receiver's elements. Answer oldObject
unless no element is equal to oldObject, in which case, raise an error.
ArrayedCollections cannot respond to this message.
remove:ifAbsent:
Remove oldObject from the receiver's elements. If several of the
elements are equal to oldObject, only one is removed. If no element is
equal to oldObject, answer the result of evaluating anExceptionBlock.
Otherwise, answer the argument, oldObject. ArrayedCollections cannot
respond to this message.
removeKey:
Remove key from the receiver.
If key is not in the receiver, notify an error.
removeKey:ifAbsent:
Remove key (and its associated value) from the receiver. If key is not in
the receiver, answer the result of evaluating aBlock. Otherwise, answer
the value externally named by key.
removeUnreferencedKeys
Undeclared removeUnreferencedKeys
scanFor:
Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or zero if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements.
select:
Evaluate aBlock with each of my values as the argument. Collect into a
new dictionary, only those associations for which aBlock evaluates to
true.
storeOn:
Refer to the comment in Object|storeOn:.
unreferencedKeys
TextConstants unreferencedKeys
valueAtNewKey:put:atIndex:declareFrom:
Support for coordinating class variable and global declarations
with variables that have been put in Undeclared so as to
redirect all references to the undeclared variable.
values
Answer a Collection containing the receiver's values.
valuesCollect:
valuesDo:
Evaluate aBlock for each of the receiver's values.
IdentityBag
Like a Bag, except that items are compared with #== instead of #= .
See the comment of IdentitySet for more information.
contentsClass
IdentityDictionary
Like a Dictionary, except that keys are compared with #== instead of #= .
See the comment of IdentitySet for more information.
fasterKeys
This was taking some time in publishing and we didn't really need a Set
keyAtValue:ifAbsent:
Answer the key that is the external name for the argument, value. If
there is none, answer the result of evaluating exceptionBlock.
keys
Answer a Set containing the receiver's keys.
scanFor:
Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or zero if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements.
IdentitySet
The same as a Set, except that items are compared using #== instead of #=.
Almost any class named IdentityFoo is the same as Foo except for the way items are compared. In Foo, #= is used, while in IdentityFoo, #== is used. That is, identity collections will treat items as the same only if they have the same identity.
For example, note that copies of a string are equal:
('abc' copy) = ('abc' copy)
but they are not identitcal:
('abc' copy) == ('abc' copy)
A regular Set will only include equal objects once:
| aSet |
aSet := Set new.
aSet add: 'abc' copy.
aSet add: 'abc' copy.
aSet
An IdentitySet will include multiple equal objects if they are not identical:
| aSet |
aSet := IdentitySet new.
aSet add: 'abc' copy.
aSet add: 'abc' copy.
aSet
asIdentitySet
scanFor:
Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or zero if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements.
KeyedIdentitySet
A KeyedIdentitySet is xxxxxxxxx.
Instance Variables
scanFor:
Same as super except change = to ==, and hash to identityHash
KeyedSet
Like Set except a key of every element is used for hashing and searching instead of the element itself. keyBlock gets the key of an element.
add:
Include newObject as one of the receiver's elements, but only if
not already present. Answer newObject.
addAll:
Include all the elements of aCollection as the receiver's elements
at:
Answer the value associated with the key.
at:ifAbsent:
Answer the value associated with the key or, if key isn't found,
answer the result of evaluating aBlock.
at:ifAbsentPut:
Answer the value associated with the key or, if key isn't found,
add the result of evaluating aBlock to self
at:ifPresent:
Lookup the given key in the receiver. If it is present, answer the value of evaluating the given block with the value associated with the key. Otherwise, answer nil.
copyEmpty
Answer an empty copy of this collection
errorKeyNotFound
fixCollisionsFrom:
The element at index has been removed and replaced by nil.
This method moves forward from there, relocating any entries
that had been placed below due to collisions with this one
includes:
Answer whether anObject is one of the receiver's elements.
includesKey:
initialize:
Initialize array to an array size of n
keyBlock:
When evaluated return the key of the argument which will be an element of the set
keys
keysDo:
keysSorted
member:
Include newObject as one of the receiver's elements, if already exists just return it
noCheckAdd:
rehash
Do nothing. Here so sending this to a Set does not have to do a time consuming respondsTo:
remove:ifAbsent:
Remove oldObject from the receiver's elements. If several of the
elements are equal to oldObject, only one is removed. If no element is
equal to oldObject, answer the result of evaluating anExceptionBlock.
Otherwise, answer the argument, oldObject. ArrayedCollections cannot
respond to this message.
removeAll
See super.
removeKey:
removeKey:ifAbsent:
scanFor:
Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or zero if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements.
Matrix
I represent a two-dimensional array, rather like Array2D.
There are three main differences between me and Array2D:
(1) Array2D inherits from ArrayedCollection, but isn't one. A lot of things that should work
do not work in consequence of this.
(2) Array2D uses "at: column at: row" index order, which means that nothing you write using
it is likely to work either. I use the almost universal "at: row at: column" order, so it is
much easier to adapt code from other languages without going doolally.
(3) Array2D lets you specify the class of the underlying collection, I don't.
Structure:
nrows : a non-negative integer saying how many rows there are.
ncols : a non-negative integer saying how many columns there are.
contents : an Array holding the elements in row-major order. That is, for a 2x3 array
the contents are (11 12 13 21 22 23). Array2D uses column major order.
You can specify the class of 'contents' when you create a new Array2D,
but Matrix always gives you an Array.
There is a reason for this. In strongly typed languages like Haskell and Clean,
'unboxed arrays' save you both space AND time. But in Squeak, while
WordArray and FloatArray and so on do save space, it costs time to use them.
A LOT of time. I've measured aFloatArray sum running nearly twice as slow as
anArray sum. The reason is that whenever you fetch an element from an Array,
that's all that happens, but when you fetch an element from aFloatArray, a whole
new Float gets allocated to hold the value. This takes time and churns memory.
So the paradox is that if you want fast numerical stuff, DON'T use unboxed arrays!
Another reason for always insisting on an Array is that letting it be something
else would make things like #, and #,, rather more complicated. Always using Array
is the simplest thing that could possibly work, and it works rather well.
I was trying to patch Array2D to make more things work, but just couldn't get my head
around the subscript order. That's why I made Matrix.
Element-wise matrix arithmetic works; you can freely mix matrices and numbers but
don't try to mix matrices and arrays (yet).
Matrix multiplication, using the symbol +* (derived from APL's +.x), works between
(Matrix or Array) +* (Matrix or Array). Don't try to use a number as an argument of +*.
Matrix * Number and Number * Matrix work fine, so you don't need +* with numbers.
Still to come: oodles of stuff. Gaussian elimination maybe, other stuff probably not.
+*
Premultiply aCollection by self. aCollection should be an Array or Matrix.
The name of this method is APL's +.x squished into Smalltalk syntax.
,
Answer a new matrix having the same number of rows as the receiver and aMatrix,
its columns being the columns of the receiver followed by the columns of aMatrix.
,,
Answer a new matrix having the same number of columns as the receiver and aMatrix,
its rows being the rows of the receiver followed by the rows of aMatrix.
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
add:
Include newObject as one of the receiver's elements. Answer newObject.
ArrayedCollections cannot respond to this message.
anyOne
Answer a representative sample of the receiver. This method can
be helpful when needing to preinfer the nature of the contents of
semi-homogeneous collections.
asArray
Answer an Array whose elements are the elements of the receiver.
Implementation note: Cannot use ''Array withAll: self'' as that only
works for SequenceableCollections which support the replacement
primitive.
asBag
Answer a Bag whose elements are the elements of the receiver.
asByteArray
Answer a ByteArray whose elements are the elements of the receiver.
Implementation note: Cannot use ''ByteArray withAll: self'' as that only
works for SequenceableCollections which support the replacement
primitive.
asCharacterSet
Answer a CharacterSet whose elements are the unique elements of the receiver.
The reciever should only contain characters.
asFloatArray
asIdentitySet
asIntegerArray
asOrderedCollection
Answer an OrderedCollection whose elements are the elements of the
receiver. The order in which elements are added depends on the order
in which the receiver enumerates its elements. In the case of unordered
collections, the ordering is not necessarily the same for multiple
requests for the conversion.
asSet
Answer a Set whose elements are the unique elements of the receiver.
asSortedArray
Return a copy of the receiver in sorted order, as an Array. 6/10/96 sw
asSortedCollection
Answer a SortedCollection whose elements are the elements of the
receiver. The sort order is the default less than or equal.
asSortedCollection:
Answer a SortedCollection whose elements are the elements of the
receiver. The sort order is defined by the argument, aSortBlock.
asWordArray
at:at:
at:at:ifInvalid:
If r,c is a valid index for this matrix, answer the corresponding element.
Otherwise, answer v.
at:at:incrementBy:
Array2D>>at:at:add: was the origin of this method, but in Smalltalk add:
generally suggests adding an element to a collection, not doing a sum.
This method, and SequenceableCollection>>at:incrementBy: that supports
it, have been renamed to reveal their intention more clearly.
at:at:put:
atAllPut:
atColumn:
atColumn:put:
atRandom
Answer a random element of the receiver. Uses a shared random
number generator owned by class Collection. If you use this a lot,
define your own instance of Random and use #atRandom:. Causes
an error if self has no elements.
atRandom:
Answer a random element of the receiver. Uses aGenerator which
    should be kept by the user in a variable and used every time. Use
    this instead of #atRandom for better uniformity of random numbers because
only you use the generator. Causes an error if self has no elements.
atRow:
atRow:put:
atRows:columns:
Answer a Matrix obtained by slicing the receiver.
rs and cs should be sequenceable collections of positive integers.
atRows:to:columns:to:
Answer a submatrix [r1..r2][c1..c2] of the receiver.
atRows:to:columns:to:ifInvalid:
Answer a submatrix [r1..r2][c1..c2] of the receiver.
Portions of the result outside the bounds of the original matrix
are filled in with element.
atRows:to:columns:to:put:
Set the [r1..r2][c1..c2] submatrix of the receiver
from the [1..r2-r1+1][1..c2-c1+1] submatrix of aMatrix.
As long as aMatrix responds to at:at: and accepts arguments in the range shown,
we don't care if it is bigger or even if it is a Matrix at all.
collect:
Answer a new matrix with transformed elements; transformations should be independent.
column:
columnCount
copy
Answer another instance just like the receiver. Subclasses typically override postCopy; they typically do not override shallowCopy.
diagonal
Answer (1 to: (nrows min: ncols)) collect: [:i | self at: i at: i]
diagonal:
difference:
Union is in because the result is always a Set.
Difference and intersection are out because the result is like the receiver,
and with irregular seleection that cannot be.
do:
Pass elements to aBlock one at a time in row-major order.
hash
I'm really not sure what would be a good hash function here.
The essential thing is that it must be compatible with #=, and
this satisfies that requirement.
identity:
identityIncludes:
Answer whether anObject is one of the receiver's elements.
identityIndexOf:
identityIndexOf:ifAbsent:
includes:
Answer whether anObject is one of the receiver's elements.
includesAllOf:
Answer whether all the elements of aCollection are in the receiver.
includesAnyOf:
Answer whether any element of aCollection is one of the receiver's elements.
indexForRow:andColumn:
indexOf:
If there are integers r, c such that (self at: r at: c) = anElement,
answer some such r@c, otherwise answer 0@0. This kind of perverse
result is provided by analogy with SequenceableCollection>>indexOf:.
The order in which the receiver are searched is UNSPECIFIED except
that it is the same as the order used by #indexOf:ifAbsent: and #readStream.
indexOf:ifAbsent:
If there are integers r, c such that (self at: r at: c) = anElement,
answer some such r@c, otherwise answer the result of anExceptionBlock.
indicesCollect:
indicesDo:
indicesInject:into:
intersection:
Union is in because the result is always a Set.
Difference and intersection are out because the result is like the receiver,
and with irregular seleection that cannot be.
isSequenceable
LIE so that arithmetic on matrices will work.
What matters for arithmetic is not that there should be random indexing
but that the structure should be stable and independent of the values of
the elements. #isSequenceable is simply the wrong question to ask.
new:
new:element:
new:tabulate:
occurrencesOf:
Answer how many of the receiver's elements are equal to anObject.
ones:
preMultiplyByArray:
Answer a +* self where a is an Array.
preMultiplyByMatrix:
Answer m +* self where m is a Matrix.
privateContents
Only used in #, #,, and #= so far.
It used to be called #contents, but that clashes with Collection>>contents.
readStream
Answer a ReadStream that returns all the elements of the receiver
in some UNSPECIFIED order.
reject:
Evaluate aBlock with each of the receiver's elements as the argument.
Collect into a new collection like the receiver only those elements for
which aBlock evaluates to false. Answer the new collection.
remove:ifAbsent:
Remove oldObject from the receiver's elements. If several of the
elements are equal to oldObject, only one is removed. If no element is
equal to oldObject, answer the result of evaluating anExceptionBlock.
Otherwise, answer the argument, oldObject. ArrayedCollections cannot
respond to this message.
replaceAll:with:
row:
rowAndColumnForIndex:
rowCount
rows:columns:
rows:columns:contents:
rows:columns:element:
rows:columns:tabulate:
select:
Evaluate aBlock with each of the receiver's elements as the argument.
Collect into a new collection like the receiver, only those elements for
which aBlock evaluates to true. Answer the new collection.
shallowCopy
Answer a copy of the receiver which shares the receiver's instance variables.
shuffled
shuffledBy:
size
Answer how many elements the receiver contains.
storeOn:
Refer to the comment in Object|storeOn:.
swap:at:with:at:
swapColumn:withColumn:
swapRow:withRow:
transposed
with:collect:
aCollection must support #at:at: and be at least as large as the receiver.
with:do:
aCollection must support #at:at: and be at least as large as the receiver.
with:inject:into:
aCollection must support #at:at: and be at least as large as the receiver.
withIndicesCollect:
withIndicesDo:
withIndicesInject:into:
zeros:
PluggableDictionary
Class PluggableDictionary allows the redefinition of hashing and equality by clients. This is in particular useful if the clients know about specific properties of the objects stored in the dictionary. See the class comment of PluggableSet for an example.
Instance variables:
hashBlock <BlockContext> A one argument block used for hashing the elements.
equalBlock <BlockContext> A two argument block used for comparing the elements.
copyEmpty
Answer an empty copy of this collection
equalBlock
Return the block used for comparing the elements in the receiver.
equalBlock:
Set a new equality block. The block must accept two arguments and return true if the argumets are considered to be equal, false otherwise
hashBlock
Return the block used for hashing the elements in the receiver.
hashBlock:
Set a new hash block. The block must accept one argument and must return the hash value of the given argument.
integerDictionary
keys
Answer a Set containing the receiver's keys.
scanFor:
Scan the key array for the first slot containing either a nil
(indicating
an empty slot) or an element that matches anObject. Answer the index

of that slot or zero if no slot is found. This method will be
overridden
in various subclasses that have different interpretations for matching

elements.
PluggableSet
PluggableSets allow the redefinition of hashing and equality by clients. This is in particular useful if the clients know about specific properties of the objects stored in the set which in turn can heavily improve the performance of sets and dictionaries.
Instance variables:
hashBlock <BlockContext> A one argument block used for hashing the elements.
equalBlock <BlockContext> A two argument block used for comparing the elements.
Example: Adding 1000 integer points in the range (0@0) to: (100@100) to a set.
| rnd set max pt |
set _ Set new: 1000.
rnd _ Random new.
max _ 100.
Time millisecondsToRun:[
1 to: 1000 do:[:i|
pt _ (rnd next * max) truncated @ (rnd next * max) truncated.
set add: pt.
].
].
The above is way slow since the default hashing function of points leads to an awful lot of collisions in the set. And now the same, with a somewhat different hash function:
| rnd set max pt |
set _ PluggableSet new: 1000.
set hashBlock:[:item| (item x bitShift: 16) + item y].
rnd _ Random new.
max _ 100.
Time millisecondsToRun:[
1 to: 1000 do:[:i|
pt _ (rnd next * max) truncated @ (rnd next * max) truncated.
set add: pt.
].
].
copyEmpty
Answer an empty copy of this collection
equalBlock
Return the block used for comparing the elements in the receiver.
equalBlock:
Set a new equality block. The block must accept two arguments and return true if the argumets are considered equal, false otherwise
hashBlock
Return the block used for hashing the elements in the receiver.
hashBlock:
Set a new hash block. The block must accept one argument and return the hash value of the given argument.
integerSet
scanFor:
Scan the key array for the first slot containing either a nil
(indicating
an empty slot) or an element that matches anObject. Answer the index

of that slot or zero if no slot is found. This method will be
overridden
in various subclasses that have different interpretations for matching

elements.
Set
I represent a set of objects without duplicates. I can hold anything that responds to
#hash and #=, except for nil. My instances will automatically grow, if necessary,
Note that I rely on #=, not #==. If you want a set using #==, use IdentitySet.
Instance structure:
array An array whose non-nil elements are the elements of the set,
and whose nil elements are empty slots. There is always at least one nil.
In fact I try to keep my "load" at 75% or less so that hashing will work well.
tally The number of elements in the set. The array size is always greater than this.
The core operation is #findElementOrNil:, which either finds the position where an
object is stored in array, if it is present, or finds a suitable position holding nil, if
its argument is not present in array,
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
add:
Include newObject as one of the receiver's elements, but only if
not already present. Answer newObject.
add:withOccurrences:
Add newObject anInteger times to the receiver. Answer newObject.
array
asSet
Answer a Set whose elements are the unique elements of the receiver.
atNewIndex:put:
atRandom:
Answer a random element of the receiver. Uses aGenerator which
    should be kept by the user in a variable and used every time. Use
    this instead of #atRandom for better uniformity of random numbers because
only you use the generator. Causes an error if self has no elements.
capacity
Answer the current capacity of the receiver.
collect:
Evaluate aBlock with each of the receiver's elements as the argument.
Collect the resulting values into a collection like the receiver. Answer
the new collection.
collect:displayingProgress:
Evaluate aBlock with each of the receiver's elements as the argument.
Collect the resulting values into a collection like the receiver. Answer
the new collection.
comeFullyUpOnReload:
Symbols have new hashes in this image.
copy
Answer another instance just like the receiver. Subclasses typically override postCopy; they typically do not override shallowCopy.
copyEmpty
Answer an empty copy of this collection
copyWithout:
Answer a copy of the receiver that does not contain any
elements equal to oldElement.
do:
Evaluate aBlock with each of the receiver's elements as the argument.
doWithIndex:
Support Set enumeration with a counter, even though not ordered
findElementOrNil:
Answer the index of a first slot containing either a nil (indicating an empty slot) or an element that matches the given object. Answer the index of that slot or zero. Fail if neither a match nor an empty slot is found.
fixCollisionsFrom:
The element at index has been removed and replaced by nil.
This method moves forward from there, relocating any entries
that had been placed below due to collisions with this one
fullCheck
Keep array at least 1/4 free for decent hash behavior
grow
Grow the elements array and reinsert the old elements
growSize
hasContentsInExplorer
includes:
Answer whether anObject is one of the receiver's elements.
initialize:
Initialize array to an array size of n
inspectorClass
Answer the class of the inspector to be used on the receiver. Called by inspect;
use basicInspect to get a normal (less useful) type of inspector.
keyAt:
May be overridden by subclasses so that fixCollisions will work
like:
Answer an object in the receiver that is equal to anObject,
nil if no such object is found. Relies heavily on hash properties
new
new:
newFrom:
niActions
niAddNewEntry
niChildrenBlockForIndexedFields
niDescription
noCheckAdd:
occurrencesOf:
Answer how many of the receiver's elements are equal to anObject.
quickRehashAllSets
rehash
Do nothing. Here so sending this to a Set does not have to do a time consuming respondsTo:
rehashAllSets
remove:ifAbsent:
Remove oldObject from the receiver's elements. If several of the
elements are equal to oldObject, only one is removed. If no element is
equal to oldObject, answer the result of evaluating anExceptionBlock.
Otherwise, answer the argument, oldObject. ArrayedCollections cannot
respond to this message.
removeAll
remove all elements from this collection.
Preserve the capacity
restoreFromSnapshot:
scanFor:
Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or zero if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements.
select:
Use copyEmpty instead of self species new to give subclasses a chance to initialize additional inst vars.
size
Answer how many elements the receiver contains.
sizeFor:
snapshotCopy
someElement
Deprecated. Use anyOne.
swap:with:
May be overridden by subclasses so that fixCollisions will work
union:
Answer the set theoretic union of the receiver and aCollection, using the receiver's notion of equality and not side effecting the receiver at all.
withArray:
private -- for use only in copy
SmallDictionary
RBSmallDictionary is a special dictionary optimized for small collections. In addition to the normal dictionary protocol, it also supports an #empty message which "empties" the collection but may hang on to the original elements (so it could collect garbage). Without #empty we would either need to create a new dictionary or explicitly remove everything from the dictionary. Both of these take more time and #empty.
Instance Variables:
keys <Array of: Object> array of keys (we don't use Associations for our key value pairs)
size <Integer> the size of the dictionary
values <Array of: Object> array of our values
=
Two dictionaries are equal if
(a) they are the same 'kind' of thing.
(b) they have the same set of keys.
(c) for each (common) key, they have the same value
add:
Include newObject as one of the receiver's elements. Answer newObject.
ArrayedCollections cannot respond to this message.
addAll:
Include all the elements of aCollection as the receiver's elements. Answer
aCollection. Actually, any object responding to #do: can be used as argument.
associationAt:
associationAt:ifAbsent:
Answer the association with the given key.
If key is not found, return the result of evaluating aBlock.
associationDeclareAt:
Return an existing association, or create and return a new one. Needed as a single message by ImageSegment.prepareToBeSaved.
associations
Answer a Collection containing the receiver's associations.
associationsDo:
Evaluate aBlock for each of the receiver's elements (key/value
associations). If any non-association is within, the error is not caught now,
but later, when a key or value message is sent to it.
associationsSelect:
Evaluate aBlock with each of my associations as the argument. Collect
into a new dictionary, only those associations for which aBlock evaluates
to true.
at:
Answer the value associated with the key.
at:ifAbsent:
Answer the value associated with the key or, if key isn't found,
answer the result of evaluating aBlock.
at:ifAbsentPut:
Return the value at the given key.
If key is not included in the receiver store the result
of evaluating aBlock as new value.
at:ifPresent:
Lookup the given key in the receiver. If it is present, answer the value of evaluating the given block with the value associated with the key. Otherwise, answer nil.
at:ifPresentAndInMemory:
Lookup the given key in the receiver. If it is present, answer the value of evaluating the given block with the value associated with the key. Otherwise, answer nil.
at:put:
Set the value at key to be anObject. If key is not found, create a
new entry for key and set is value to anObject. Answer anObject.
capacity
Answer the current capacity of the receiver.
collect:
Evaluate aBlock with each of my values as the argument. Collect the
resulting values into a collection that is like me. Answer with the new
collection.
copy
Answer another instance just like the receiver. Subclasses typically override postCopy; they typically do not override shallowCopy.
customizeExplorerContents
declare:from:
Add key to the receiver. If key already exists, do nothing. If aDictionary
includes key, then remove it from aDictionary and use its association as
the element of the receiver.
do:
Evaluate aBlock with each of the receiver's elements as the argument.
empty
errorKeyNotFound
errorValueNotFound
explorerContentsWithIndexCollect:
findIndexForKey:
flattenOnStream:
seems to not be the best solution to do that.
Imagine if the class Stream should have a method #writeSomething for each object existing in Pharo.
Objects themeself have the information on how to be print . Not the stream.
growKeysAndValues
growTo:
hasBindingThatBeginsWith:
Answer true if the receiver has a key that begins with aString, false otherwise
includes:
Answer whether anObject is one of the receiver's elements.
includesAssociation:
includesIdentity:
Answer whether aValue is one of the values of the receiver. Contrast #includes: in which there is only an equality check, here there is an identity check
includesKey:
Answer whether the receiver has a key equal to the argument, key.
initialize
Subclasses should redefine this method to perform initializations on instance creation
isDictionary
keyAtIdentityValue:
Answer the key that is the external name for the argument, value. If
there is none, answer nil.
Note: There can be multiple keys with the same value. Only one is returned.
keyAtIdentityValue:ifAbsent:
Answer the key that is the external name for the argument, value. If
there is none, answer the result of evaluating exceptionBlock.
Note: There can be multiple keys with the same value. Only one is returned.
keyAtValue:
Answer the key that is the external name for the argument, value. If
there is none, answer nil.
keyAtValue:ifAbsent:
Answer the key that is the external name for the argument, value. If
there is none, answer the result of evaluating exceptionBlock.
: Use =, not ==, so stings like 'this' can be found. Note that MethodDictionary continues to use == so it will be fast.
keyForIdentity:
If aValue is one of the values of the receive, return its key, else return nil. Contrast #keyAtValue: in which there is only an equality check, here there is an identity check
keys
Answer a Set containing the receiver's keys.
keysAndValuesDo:
keysAndValuesRemove:
Removes all entries for which keyValueBlock returns true.
keysDo:
keysSortedSafely
Answer a SortedCollection containing the receiver's keys.
new
new:
occurrencesOf:
Answer how many of the receiver's elements are equal to anObject.
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
printElementsOn:
The original code used #skip:, but some streams do not support that,
and we don't really need it.
privateAt:put:
rehash
we don't use hashing, nothing to be done
remove:
Remove oldObject from the receiver's elements. Answer oldObject
unless no element is equal to oldObject, in which case, raise an error.
ArrayedCollections cannot respond to this message.
remove:ifAbsent:
Remove oldObject from the receiver's elements. If several of the
elements are equal to oldObject, only one is removed. If no element is
equal to oldObject, answer the result of evaluating anExceptionBlock.
Otherwise, answer the argument, oldObject. ArrayedCollections cannot
respond to this message.
removeKey:
Remove key from the receiver.
If key is not in the receiver, notify an error.
removeKey:ifAbsent:
Remove key (and its associated value) from the receiver. If key is not in
the receiver, answer the result of evaluating aBlock. Otherwise, answer
the value externally named by key.
removeUnreferencedKeys
Undeclared removeUnreferencedKeys
scanFor:
Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or zero if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements.
select:
Evaluate aBlock with each of my values as the argument. Collect into a
new dictionary, only those associations for which aBlock evaluates to
true.
size
Answer how many elements the receiver contains.
storeOn:
Refer to the comment in Object|storeOn:.
unreferencedKeys
TextConstants unreferencedKeys
values
Answer a Collection containing the receiver's values.
valuesDo:
Evaluate aBlock for each of the receiver's values.
SmallIdentityDictionary
I'm a SmallDictionary (this means faster than default one when dealing with limited number of items)
but I check my key based on identity.
findIndexForKey: