Dictionary.st
changeset 20228 54e93c9d0126
parent 20224 d075f60fbd7b
child 20229 b5cdb27022c8
child 20239 cc11bc01e248
equal deleted inserted replaced
20227:4090cde0c345 20228:54e93c9d0126
    39 documentation
    39 documentation
    40 "
    40 "
    41     a Dictionary is (conceptionally) a set of Associations storing key-value pairs.
    41     a Dictionary is (conceptionally) a set of Associations storing key-value pairs.
    42     (The implementation uses two arrays to store the keys and values separately.)
    42     (The implementation uses two arrays to store the keys and values separately.)
    43     Searching for an element is done using a hash into the key array.
    43     Searching for an element is done using a hash into the key array.
    44     Another way of looking at a dictionary is as a array which uses
    44     Another way of looking at a dictionary is as an array that uses
    45     arbitrary access keys (i.e. not just integers as arrays do).
    45     arbitrary access keys (i.e. not just integers as arrays do).
    46 
    46 
    47     Since the keys are unordered, no internal element order is defined
    47     Since the keys are unordered, no internal element order is defined
    48     (i.e. enumerating them may return elements in any order - even changing
    48     (i.e. enumerating them may return elements in any order - even changing
    49      over time).
    49      over time).
   129 
   129 
   130     d1 := Dictionary withKeys:#(a b c) andValues:#( 1 2 3).
   130     d1 := Dictionary withKeys:#(a b c) andValues:#( 1 2 3).
   131     d2 := Dictionary newFrom:d1.
   131     d2 := Dictionary newFrom:d1.
   132     d2.
   132     d2.
   133                                                                         [exEnd]
   133                                                                         [exEnd]
   134                                                                             
   134 
   135 "
   135 "
   136 ! !
   136 ! !
   137 
   137 
   138 !Dictionary class methodsFor:'instance creation'!
   138 !Dictionary class methodsFor:'instance creation'!
   139 
   139 
   214         d at:each put:(aOneArgBlock value:each).
   214         d at:each put:(aOneArgBlock value:each).
   215     ].
   215     ].
   216     ^ d
   216     ^ d
   217 
   217 
   218     "
   218     "
   219      Dictionary withKeys:#(10 20 30 40 50 60 70 80 90) valueBlock:[:e| e asString] 
   219      Dictionary withKeys:#(10 20 30 40 50 60 70 80 90) valueBlock:[:e| e asString]
   220     "
   220     "
   221 !
   221 !
   222 
   222 
   223 withKeysAndValues:anArray
   223 withKeysAndValues:anArray
   224     "return a new instance where keys and values are taken from alternating
   224     "return a new instance where keys and values are taken from alternating
   249         d at:(aOneArgBlock value:each) put:each.
   249         d at:(aOneArgBlock value:each) put:each.
   250     ].
   250     ].
   251     ^ d
   251     ^ d
   252 
   252 
   253     "
   253     "
   254      Dictionary withValues:#(10 20 30 40 50 60 70 80 90) keyBlock:[:e| e asString] 
   254      Dictionary withValues:#(10 20 30 40 50 60 70 80 90) keyBlock:[:e| e asString]
   255     "
   255     "
   256 ! !
   256 ! !
   257 
   257 
   258 !Dictionary class methodsFor:'Compatibility-Squeak'!
   258 !Dictionary class methodsFor:'Compatibility-Squeak'!
   259 
   259 
   267     ^ self withAssociations:aCollectionOfAssociations
   267     ^ self withAssociations:aCollectionOfAssociations
   268 
   268 
   269     "
   269     "
   270      Dictionary newFrom:{#foo -> #Foo. #bar -> #Bar}
   270      Dictionary newFrom:{#foo -> #Foo. #bar -> #Bar}
   271 
   271 
   272      Dictionary 
   272      Dictionary
   273         newFrom:(Dictionary withKeysAndValues:#('one' 1 'two' 2 'three' 3 'four' 4))
   273         newFrom:(Dictionary withKeysAndValues:#('one' 1 'two' 2 'three' 3 'four' 4))
   274     "
   274     "
   275 ! !
   275 ! !
   276 
   276 
   277 !Dictionary methodsFor:'Compatibility-Dolphin'!
   277 !Dictionary methodsFor:'Compatibility-Dolphin'!
   292         ( aDictionary at: key ifAbsent: [ ^false ] ) = value
   292         ( aDictionary at: key ifAbsent: [ ^false ] ) = value
   293         ifFalse: [ ^false ]
   293         ifFalse: [ ^false ]
   294     ].
   294     ].
   295     ^ true
   295     ^ true
   296 ! !
   296 ! !
   297 
       
   298 
   297 
   299 
   298 
   300 !Dictionary methodsFor:'accessing'!
   299 !Dictionary methodsFor:'accessing'!
   301 
   300 
   302 associationAt:aKey
   301 associationAt:aKey
   369 	^ valueArray basicAt:index
   368 	^ valueArray basicAt:index
   370     ].
   369     ].
   371     ^ exceptionBlock value.
   370     ^ exceptionBlock value.
   372 !
   371 !
   373 
   372 
   374 at:aKey ifAbsent:default update:aBlock 
   373 at:aKey ifAbsent:default update:aBlock
   375     "update the element stored under aKey with the result from 
   374     "update the element stored under aKey with the result from
   376      evaluating aBlock with the previous stored value as argument, or with default,
   375      evaluating aBlock with the previous stored value as argument, or with default,
   377      if there was no such key initially.
   376      if there was no such key initially.
   378      I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey ifAbsent:default)).
   377      I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey ifAbsent:default)).
   379      Return the new value stored.
   378      Return the new value stored.
   380      This is an optimized accessor, which only computes the hash value once."
   379      This is an optimized accessor, which only computes the hash value once."
   480 
   479 
   481     "
   480     "
   482      |d|
   481      |d|
   483      d := Dictionary new.
   482      d := Dictionary new.
   484      d at:#foo put:'yes this is foo'.
   483      d at:#foo put:'yes this is foo'.
   485      
   484 
   486      d at:#foo ifPresent:[:val | Transcript showCR:'the value of foo is: ',val].
   485      d at:#foo ifPresent:[:val | Transcript showCR:'the value of foo is: ',val].
   487      d at:#bar ifPresent:[:val | Transcript showCR:'the value of bar is: ',val].
   486      d at:#bar ifPresent:[:val | Transcript showCR:'the value of bar is: ',val].
   488     "
   487     "
   489 !
   488 !
   490 
   489 
   531     ].
   530     ].
   532 
   531 
   533     index := self findKeyOrNil:k.
   532     index := self findKeyOrNil:k.
   534     (keyArray basicAt:index) notNil ifTrue:[
   533     (keyArray basicAt:index) notNil ifTrue:[
   535         "/ key already present
   534         "/ key already present
   536         ^ aBlock value:(valueArray basicAt:index). 
   535         ^ aBlock value:(valueArray basicAt:index).
   537     ].
   536     ].
   538     "/ a new key
   537     "/ a new key
   539     keyArray basicAt:index put:k.
   538     keyArray basicAt:index put:k.
   540     valueArray basicAt:index put:anObject.
   539     valueArray basicAt:index put:anObject.
   541     tally := tally + 1.
   540     tally := tally + 1.
   550      d at:'foo' put:1234 ifPresent:[:v| self error: 'duplicate: ', v printString ].
   549      d at:'foo' put:1234 ifPresent:[:v| self error: 'duplicate: ', v printString ].
   551      d at:'foo' put:1234 ifPresent:[:v| self halt:'duplicate: ', v printString. 5555 ].
   550      d at:'foo' put:1234 ifPresent:[:v| self halt:'duplicate: ', v printString. 5555 ].
   552     "
   551     "
   553 !
   552 !
   554 
   553 
   555 at:aKey update:aBlock 
   554 at:aKey update:aBlock
   556     "update the element stored under aKey with the result from 
   555     "update the element stored under aKey with the result from
   557      evaluating aBlock with the previous stored value as argument.
   556      evaluating aBlock with the previous stored value as argument.
   558      Report an error if there was no such key initially.
   557      Report an error if there was no such key initially.
   559      I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey)).
   558      I.e. this is the same as self at:aKey put:(aBlock value:(self at:aKey)).
   560      Return the new value stored.
   559      Return the new value stored.
   561      This is an optimized accessor, which only computes the hash value once."
   560      This is an optimized accessor, which only computes the hash value once."
   956     ^ Association key:key value:(self removeKey:key)
   955     ^ Association key:key value:(self removeKey:key)
   957 
   956 
   958     "Modified: 1.3.1996 / 21:21:11 / cg"
   957     "Modified: 1.3.1996 / 21:21:11 / cg"
   959 !
   958 !
   960 
   959 
   961 removeIdentityValue:aValue ifAbsent:aBlock 
   960 removeIdentityValue:aValue ifAbsent:aBlock
   962     "remove (first) the association to aValue from the collection,
   961     "remove (first) the association to aValue from the collection,
   963      return the key under which it was stored previously.
   962      return the key under which it was stored previously.
   964      If it was not in the collection return result from evaluating aBlock.
   963      If it was not in the collection return result from evaluating aBlock.
   965      The value is searched using identity compare.
   964      The value is searched using identity compare.
   966 
   965 
   971              See #saveRemoveValue: to do this."
   970              See #saveRemoveValue: to do this."
   972     
   971     
   973     |next   "{ Class:SmallInteger }"
   972     |next   "{ Class:SmallInteger }"
   974      oldKey|
   973      oldKey|
   975 
   974 
   976     keyArray 
   975     keyArray
   977         keysAndValuesDo:[:index :aKey | 
   976         keysAndValuesDo:[:index :aKey |
   978             |idx "{Class:SmallInteger}"|
   977             |idx "{Class:SmallInteger}"|
   979 
   978 
   980             (aKey notNil and:[ aKey ~~ DeletedEntry ]) ifTrue:[
   979             (aKey notNil and:[ aKey ~~ DeletedEntry ]) ifTrue:[
   981                 idx := index.
   980                 idx := index.
   982                 ((valueArray at:idx) == aValue) ifTrue:[
   981                 ((valueArray at:idx) == aValue) ifTrue:[
  2174 ! !
  2173 ! !
  2175 
  2174 
  2176 !Dictionary methodsFor:'searching'!
  2175 !Dictionary methodsFor:'searching'!
  2177 
  2176 
  2178 findFirst:aBlock ifNone:exceptionValue
  2177 findFirst:aBlock ifNone:exceptionValue
  2179     "find the index of the first element, for which evaluation of the argument, aBlock returns true; 
  2178     "find the index of the first element, for which evaluation of the argument, aBlock returns true;
  2180      return its index or the value from exceptionValue if none detected.
  2179      return its index or the value from exceptionValue if none detected.
  2181      This is much like #detect:ifNone:, however, here an INDEX is returned,
  2180      This is much like #detect:ifNone:, however, here an INDEX is returned,
  2182      while #detect:ifNone: returns the element.
  2181      while #detect:ifNone: returns the element.
  2183 
  2182 
  2184      Here we return the first key for which aBlock matches the value.
  2183      Here we return the first key for which aBlock matches the value.