eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'KeyedCollection':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: KeyedCollection


Inheritance:

   Object
   |
   +--Collection
      |
      +--KeyedCollection
         |
         +--AbstractTime::PrintBindingMirror
         |
         +--BTree
         |
         +--MethodDictionary
         |
         +--RBSmallDictionary
         |
         +--SmallDictionary
         |
         +--TSTree

Package:
stx:libbasic
Category:
Collections-Abstract
Version:
rev: 1.45 date: 2024/03/05 15:25:27
user: cg
file: KeyedCollection.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


Abstract superclass for collections which have a key->value mapping.
This abstract class provides functionality common to those collections,
without knowing how the concrete class implements things. 
Thus, all methods found here depend on some basic mechanisms 
to be defined in the concrete class. 
These basic methods are usually defined as #subclassResponsibility here.
Some methods are also redefined for better performance.

Subclasses should at least implement:
    at:ifAbsent:        - accessing elements
    removeKey:ifAbsent  - removing
    keysAndValuesDo:    - enumerating

copyright

COPYRIGHT (c) 1998 by eXept Software AG All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

instance creation
o  decodeFromLiteralArray: anArray
create & return a new instance from information encoded in anArray.

o  newWithCapacity: size
return a new empty Collection preferrably with capacity for n elements

o  withAll: aCollection
create a KeyedCollection from another Collection with keys

Usage example(s):

        |d|

        d := Dictionary withKeys:#(a b c d e) andValues:#(1 2 3 4 5).
        SmallDictionary withAll:d.

        SmallDictionary withAll:#('one' 'two' 'three' 'four').

o  withAssociations: aCollectionOfAssociations
return a new instance where associations are taken from the argument

Usage example(s):

     SmallDictionary withAssociations:{ #'one'->1 .
                                   #'two'->2 .
                                   #'three'->3 .
                                   #'four'->4 }

o  withKeyValuePairs: aCollection
return a new instance where keys and values are taken from
elements of aCollection, which are pairs (2-element SeuqenceableCollection) of key and value

Usage example(s):

     SmallDictionary withKeyValuePairs:#( ('one' 1) ('two' 2) ('three' 3) ('four' 4))

o  withKeys: keyCollection andValues: valueCollection
return a new instance where keys and values are taken from
the argumentArrays.
It is ok for the keyArray to have less elements than valueArray;
(i.e. only those first keys are defined)

Usage example(s):

     SmallDictionary withKeys:#(one two three) andValues:#(1 2 3)
     SmallDictionary withKeys:#(one two three) andValues:#(1 2 3 4 5 6)

o  withKeysAndValues: aSequenceableCollection
return a new instance where keys and values are taken from alternating
elements of aSequenceableCollection

Usage example(s):

     SmallDictionary withKeysAndValues:#('one' 1 'two' 2 'three' 3 'four' 4)
     SmallDictionary withKeysAndValues:#('one' 1 'two' 2 'three' 3 'incomplete')

queries
o  isAbstract
Return if this class is an abstract class.
True is returned for KeyedCollection here; false for subclasses.
Abstract subclasses must redefine this again.


Instance protocol:

accessing
o  associationAt: aKey
return an association consisting of aKey and the element indexed
by aKey -
report an error, if no element is stored under aKey.

o  associationAt: aKey ifAbsent: exceptionBlock
return an association consisting of aKey and the element indexed by aKey -
return result of exceptionBlock if no element is stored under aKey.
Warning: this is a comatibility interface only, with a different semantic as
the original ST80 implementation. The returned assoc is created on the fly,
and not the one stored in the receiver (there are not assocs there)

o  associations
return an ordered collection containing the receiver's associations.

o  at: key
return the value stored under akey.
Raise an error if not found

o  at: key ifAbsent: exceptionBlock
return the value stored under akey.
Return the value from evaluating exceptionBlock if not found

** This method must be redefined in concrete classes (subclassResponsibility) **

o  at: aKey ifAbsent: default update: aBlock
update the element stored under aKey with the result from
evaluating aBlock with the previous stored value as argument, or with default,
if there was no such key initially.
Return the new value stored.

o  at: aKey ifAbsentPut: valueBlock
return the element indexed by aKey if present,
if not present, store the result of evaluating valueBlock
under aKey and return it.
WARNING: do not add elements while iterating over the receiver.
Iterate over a copy to do this.

o  at: aKey put: anObject
add the argument anObject under key, aKey to the receiver.
Return anObject (sigh).
WARNING: do not add elements while iterating over the receiver.
Iterate over a copy to do this.

** This method must be redefined in concrete classes (subclassResponsibility) **

o  at: aKey put: anObject ifPresent: aBlock
if the receiver contains an element stored under aKey,
retrieve it and evaluate aBlock passing the element as argument,
return the block's value.
If not, store aValue under the key.
Use this with an error-reporting block, to ensure that no keys are reused

o  at: aKey update: aBlock
update the element stored under aKey with the result from
evaluating aBlock with the previous stored value as argument.
Report an error if there was no such key initially.
Return the new value stored.

o  at: aKey update: aBlock ifAbsent: absentBlock
update the element stored under aKey with the result from
evaluating aBlock with the previous stored value as argument.
Evaluate absentBlock and return its value if there was no such key initially.
Otherwise return the new value stored.

o  keyAtEqualValue: value
return the key under which value is stored.
Raise an error if not found.
This is a slow access, since the receiver is searched sequentially.
NOTICE:
The value is searched using equality compare

o  keyAtEqualValue: value ifAbsent: exceptionBlock
return the key under which value is stored.
If not found, return the value from evaluating exceptionBlock.
This is a slow access, since the receiver is searched sequentially.
NOTICE:
The value is searched using equality compare

o  keyAtIdenticalValue: value
return the key under which value is stored.
Raise an error if not found.
This is a slow access, since the receiver is searched sequentially.
NOTICE:
The value is searched using identity compare

o  keyAtIdenticalValue: value ifAbsent: exceptionBlock
return the key under which value is stored.
If not found, return the value from evaluating exceptionBlock.
This is a slow access, since the receiver is searched sequentially.
NOTICE:
The value is searched using identity compare

o  keyAtValue: value
return the key under which value is stored.
Raise an error if not found.
This is a slow access, since the receiver is searched sequentially.
NOTICE:
The value is searched using equality compare

o  keyAtValue: value ifAbsent: exceptionBlock
return the key under which value is stored.
If not found, return the value from evaluating exceptionBlock.
This is a slow access, since the receiver is searched sequentially.
NOTICE:
The value is searched using equality compare

o  keys
return a collection containing the keys of the receiver

adding
o  , anotherDictionaryOrAssociation
return a new dictionary containing a merged set of associations.
If anotherDictionaryOrAssociation includes any of the receiver's keys,
the value from anotherDictionaryOrAssociation will be placed into the
returned result.

o  addAll: aCollection
ANSI 5.7.2.1:
Message: addAll: dictionary
Synopsis
Store the elements of dictionary in the receiver at the
corresponding keys from dictionary.
Definition: <abstractDictionary>
This message is equivalent to repeatedly sending the #at:put:
message to the receiver with each of the keys and elements in
dictionary in turn. If a key in dictionary is key equivalent
to a key in the receiver, the associated element in dictionary
replaces the element in the receiver.

Returns the argument, aCollection.

WARNING: do not add elements while iterating over the receiver.
Iterate over a copy to do this.

Usage example(s):

     |d1 d2|

     d1 := Dictionary new.
     d1 at:1 put:'one'.
     d1 at:2 put:'two'.
     d2 := Dictionary new.
     d2 at:3 put:'three'.
     d2 at:4 put:'four'.
     d1 addAll:d2.
     d1.

o  declareAllFrom: aDictionaryOrNil
merge all key-value pairs from aDictionary into the receiver.
Values present in the arg will always end up in the receiver;
i.e. even if a value coming from the argument is already in the receiver,
the value from aDictionaryOrNil is stored into the receiver.

sigh:
For compatibility with #declare:from: the behavior should be changed as following:
If the receiver already contains a key, the existing value is retained.
To keep the compatibility with other smalltalks, the semantics of this remains
as is, and #declareAllNewFrom: was added for convenience.
See #declareAllNewFrom: which does exactly what this name implies.

o  declareAllNewFrom: aDictionaryOrNil
merge all new key-value pairs from aDictionary into the receiver
i.e. If the receiver already contains a key, the existing value is retained.
See also #declareAllFrom:

o  testAndAdd: anAssociation
add anAssociation to myself, if anAssociation's key is not already present.
Answer true, if anAssociation's key was already in the collection.

comparing
o  = aKeyedCollection
return true, if the argument is an SmallDictionary containing the same
key-value pairs as I do

o  hash
return a hash key for the receiver

Usage example(s):

this hash is stupid - but for larger collections, the hashing
     time can become much bigger than the time lost in added probing.
     Time will show ...
     Notice & warning:
        if the #= method is ever changed to compare non-dictionaries equal,
        the code below must be changed to assert that the same hash-value is
        still returned.
        (which may be hard to accomplish)

Usage example(s):

     |d|

     d := SmallDictionary new.
     d at:1 put:'one'.
     d at:'one' put:1.
     d at:2 put:#two.
     d at:'two' put:2.
     d hash

o  sameContentsAs: aKeyedCollection
answer true, if all the elements in self and aCollection
are common, i.e. aDictionary contains the same
key-value pairs as I do

converting
o  literalArrayEncoding
|dict|

dict := SmallDictionary new.
dict at:1 put:'bla'.
dict at:'fasel' put:#[1 2 3 4].
dict literalArrayEncoding

enumerating
o  associationsCollect: aBlock
for each key-value pair in the receiver, evaluate the argument, aBlock
and return a collection with the results.

See also:
#keysAndValuesCollect: (which passes separate keys & values)
#collect: (which only passes values)

This is much like #keysAndValuesCollect:, but aBlock gets the
key and value as a single association argument.
#keysAndValuesCollect: and is a bit faster therefore (no intermediate objects).

WARNING: do not add/remove elements while iterating over the receiver.
Iterate over a copy to do this.

Usage example(s):

     |ages|

     ages := SmallDictionary new.
     ages at:'cg' put:37.
     ages at:'ca' put:33.
     ages at:'sv' put:36.
     ages at:'tk' put:28.
     ages associationsCollect:[:assoc |
                assoc key , '''s age is ' , assoc value printString]

o  associationsDo: aBlock
perform the block for all associations in the collection.

See also:
#do: (which passes values to its block)
#keysDo: (which passes only keys to its block)
#keysAndValuesDo: (which passes keys&values)

This is much like #keysAndValuesDo:, but aBlock gets the
key and value as a single association argument.
#keysAndValuesDo: and is a bit faster therefore (no intermediate objects).

WARNING: do not add/remove elements while iterating over the receiver.
Iterate over a copy to do this.

o  associationsDo: aBlock separatedBy: sepBlock
perform the block for all associations in the collection.

See also:
#do: (which passes values to its block)
#keysDo: (which passes only keys to its block)
#keysAndValuesDo: (which passes keys&values)

This is much like #keysAndValuesDo:, but aBlock gets the
key and value as a single association argument.
#keysAndValuesDo: and is a bit faster therefore (no intermediate objects).

WARNING: do not add/remove elements while iterating over the receiver.
Iterate over a copy to do this.

o  associationsReverseDo: aBlock
perform the block for all associations in the collection.
Since dictionary does not define any order of its elements,
this is the same as #associationsDo: here.
Provided for protocol compatibility with OrderedDictionary

o  associationsSelect: aBlock
return a new collection with all elements from the receiver, for which
the argument aBlock evaluates to true.
The block gets keys and values as an association argument.

See also: #keysAndValuesSelect: (which is slightly faster),
#select: (which only passes the value)

This is much like #keysAndValuesSelect:, but aBlock gets the
key and value as a single association argument.
#keysAndValuesSelect: and is a bit faster therefore (no intermediate objects).

WARNING: do not add/remove elements while iterating over the receiver.
Iterate over a copy to do this.

Usage example(s):

     |ages|

     ages := SmallDictionary new.
     ages at:'cg' put:37.
     ages at:'ca' put:33.
     ages at:'sv' put:36.
     ages at:'tk' put:28.

     ages associationsSelect:[:assoc |
                (assoc key startsWith:'c') or:[assoc value < 30]].

o  do: aBlock
evaluate aBlock for each value

o  keysAndValuesDo: aBlock
evaluate aBlock for each key and value

** This method must be redefined in concrete classes (subclassResponsibility) **

o  keysAndValuesReverseDo: aBlock
evaluate aBlock for each key and value in reverse order

** This method must be redefined in concrete classes (subclassResponsibility) **

o  keysAndValuesSelect: aBlock
return a new collection with all elements from the receiver, for which
the argument aBlock evaluates to true.
The block gets keys and values as separate arguments.

See also:
#associationsSelect: (which passes key-value pairs),
#keysSelect: (which passes key values),
#select: (which only passes the value)

This is much like #associationsSelect:, but aBlock gets the
key and value as two separate arguments.
#associationsSelect: is a bit slower.

WARNING: do not add/remove elements while iterating over the receiver.
Iterate over a copy to do this.

Usage example(s):

     |ages|

     ages := SmallDictionary new.
     ages at:'cg' put:37.
     ages at:'ca' put:33.
     ages at:'sv' put:36.
     ages at:'tk' put:28.

     ages keysAndValuesSelect:[:name :age |
                (name startsWith:'c') or:[age < 30]].

o  keysSelect: aBlock
return a new collection with all elements from the receiver, for which
the argument aBlock evaluates to true.
The block gets the individual keys as its single argument.

See also:
#associationsSelect: (which passes key->value associations),
#keysAndValuesSelect: (which passes key & value args)
#select: (which passes values as arg),

WARNING: do not add/remove elements while iterating over the receiver.
Iterate over a copy to do this.

Usage example(s):

     |d|

     d := SmallDictionary new.
     d at:#foo put:#bar.
     d at:#bar put:#baz.
     d at:#baz put:#foo.

     d keysSelect:[:el | el startsWith:'b'].

o  printElementsDo: aBlock
redefined, so #printOn: prints associations

o  reverseDo: aBlock
evaluate aBlock for each value in reverse order

o  select: aBlock
return a new collection with all elements from the receiver, for which
the argument aBlock evaluates to true.
The block gets the individual values as its single argument.

See also:
#associationsSelect: (which passes key->value associations),
#keysAndValuesSelect: (which passes key & value args)
#keysSelect: (which passes key values),

WARNING: do not add/remove elements while iterating over the receiver.
Iterate over a copy to do this.

Usage example(s):

     |d|

     d := SmallDictionary new.
     d at:#foo put:#bar.
     d at:#bar put:#baz.
     d at:#baz put:#foo.

     d select:[:el | el startsWith:'b'].

misc ui support
o  inspectorClass
( an extension from the stx:libtool package )
redefined to use DictionaryInspector
(instead of the default Inspector).

private
o  fastSizeOr0
optimization for subclasses that can provide the collection's size in a fast way

queries
o  includesAssociation: anAssociation
return true, if there is an association in the receiver with the
same key and value as the argument, anAssociation.
NOTICE: in contrast to #includes:, this compares both key and value.

o  includesIdenticalKey: aKey
return true, if the argument, aKey is a key in the receiver

o  includesKey: aKey
return true, if the argument, aKey is a key in the receiver

removing
o  dropAllSuchThat: conditionBlockOnValueOrKeyAndValue
Apply the condition block to each key and value (if it is a 2-arg block)
or to each value (if it is a one arg block)
and drop the entry (key and value) if the condition is true.
Differs from #removeAllSuchThat:
returns self instead of a collection containing the removed elements.

Usage example(s):

     |d|

     d := SmallDictionary new.
     d at:'one' put:1.
     d at:'two' put:2.
     d at:'three' put:3.
     d at:'four' put:4.
     d at:'uno' put:1.
     d at:'due' put:2.
     d at:'tre' put:3.
     d at:'eins' put:1.
     d at:'zwei' put:2.
     d at:'drei' put:3.

     d dropAllSuchThat:[:k :v | k startsWith:'t'].
     d dropAllSuchThat:[:k :v | v = 2].
     d inspect

o  removeAllKeys: aCollection
remove all keys of the argument, aCollection from the receiver.
Raises an error, if some element-to-remove is not in the receiver.

o  removeAllSuchThat: conditionBlockOnValueOrKeyAndValue
Apply the condition block to each key and value (if it is a 2-arg block)
or to each value (if it is a one arg block)
and remove the entry (key and value) if the condition is true.
Return a collection of removed associations.

Usage example(s):

     |d removed|

     d := SmallDictionary new.
     d at:'one' put:1.
     d at:'two' put:2.
     d at:'three' put:3.
     d at:'four' put:4.
     d at:'uno' put:1.
     d at:'due' put:2.
     d at:'tre' put:3.
     d at:'eins' put:1.
     d at:'zwei' put:2.
     d at:'drei' put:3.

     removed := d removeAllSuchThat:[:k :v | k startsWith:'t'].
     self assert:(removed keys asOrderedCollection sorted sameContentsAs:#('three'  'tre' 'two') sorted).

     d declareAllFrom:removed.

     removed := d removeAllSuchThat:[:k :v | v = 2].
     self assert:(removed keys asOrderedCollection sorted sameContentsAs:#('two'  'zwei' 'due') sorted).

o  removeAssociation: assoc
remove the association from the collection.
If it was not in the collection report an error.
Only the key is used in the passed argument, and a new
association, for the key and the previously stored value is returned.

WARNING: do not remove elements while iterating over the receiver.
See #safeRemoveKey: to do this.

o  removeKey: aKey
remove key (and the value stored under that key) from the
receiver; raise an error if no such element is contained

o  removeKey: aKey ifAbsent: exceptionBlock
remove key (and the value stored under that key) from the
receiver; return the value which was stored previously there.
If no such element is contained, return the value
from evaluating exceptionBlock

** This method must be redefined in concrete classes (subclassResponsibility) **

searching
o  findFirst: aBlock ifNone: exceptionValue
find the index of the first element, for which evaluation of the argument, aBlock returns true;
return its index or the value from exceptionValue if none detected.
This is much like #detect:ifNone:, however, here an INDEX is returned,
while #detect:ifNone: returns the element.

Here we return the first key for which aBlock matches the value.
Note that there is no order in a Dictionary, so any element is first.

Usage example(s):

        (KeyValueList withKeys:#('a' 'b' 'c') andValues:#('bla' 'hello' 'hallo'))
            findFirst:[:v| v first = $h].

o  findFirstKey: aBlock
find and return the first key, for which evaluation of the argument, aBlock
returns true; return nil if none is detected.



ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sat, 21 Dec 2024 16:40:06 GMT