KeyedCollection.st
changeset 21653 baee5890dca8
parent 21649 4a09b7965b34
child 21655 058cafb6c2f6
equal deleted inserted replaced
21652:927a47057848 21653:baee5890dca8
   128     ^ self == KeyedCollection
   128     ^ self == KeyedCollection
   129 ! !
   129 ! !
   130 
   130 
   131 !KeyedCollection methodsFor:'accessing'!
   131 !KeyedCollection methodsFor:'accessing'!
   132 
   132 
   133 associationAt:key 
   133 associationAt:aKey 
   134     "return an association consisting of aKey and the element indexed 
   134     "return an association consisting of aKey and the element indexed 
   135      by aKey - 
   135      by aKey - 
   136      report an error, if no element is stored under aKey."
   136      report an error, if no element is stored under aKey."
   137 
   137 
   138     ^ Association key:key value:(self at:key)
   138     ^ self associationAt:aKey ifAbsent:[self errorKeyNotFound:aKey]
       
   139 
       
   140     "Modified: / 16-03-2017 / 17:19:52 / stefan"
       
   141 !
       
   142 
       
   143 associationAt:aKey ifAbsent:exceptionBlock
       
   144     "return an association consisting of aKey and the element indexed by aKey -
       
   145      return result of exceptionBlock if no element is stored under aKey.
       
   146      Warning: this is a comatibility interface only, with a different semantic as
       
   147               the original ST80 implementation. The returned assoc is created on the fly,
       
   148               and not the one stored in the receiver (there are not assocs there)"
       
   149 
       
   150     |value|
       
   151 
       
   152     value := self at:aKey ifAbsent:[^ exceptionBlock value].
       
   153     ^ Association key:aKey value:value.
       
   154 
       
   155     "Created: / 16-03-2017 / 17:17:05 / stefan"
       
   156 !
       
   157 
       
   158 associations
       
   159     "return an ordered collection containing the receiver's associations."
       
   160 
       
   161     |coll|
       
   162 
       
   163     coll := OrderedCollection new.
       
   164     self associationsDo:[:assoc | coll add:assoc].
       
   165     ^ coll
       
   166 
       
   167     "Created: / 16-03-2017 / 17:30:47 / stefan"
   139 !
   168 !
   140 
   169 
   141 at:key
   170 at:key
   142     "return the value stored under akey.
   171     "return the value stored under akey.
   143      Raise an error if not found"
   172      Raise an error if not found"
   154     ^ self subclassResponsibility
   183     ^ self subclassResponsibility
   155 
   184 
   156     "Created: / 19.6.1998 / 00:48:23 / cg"
   185     "Created: / 19.6.1998 / 00:48:23 / cg"
   157 !
   186 !
   158 
   187 
       
   188 at:aKey ifAbsent:default update:aBlock
       
   189     "update the element stored under aKey with the result from
       
   190      evaluating aBlock with the previous stored value as argument, or with default,
       
   191      if there was no such key initially.
       
   192      Return the new value stored."
       
   193 
       
   194     ^ self at:aKey put:(aBlock value:(self at:aKey ifAbsent:default))
       
   195 
       
   196     "Created: / 16-03-2017 / 17:28:15 / stefan"
       
   197 !
       
   198 
       
   199 at:aKey ifAbsentPut:valueBlock
       
   200     "return the element indexed by aKey if present,
       
   201      if not present, store the result of evaluating valueBlock
       
   202      under aKey and return it.
       
   203      WARNING: do not add elements while iterating over the receiver.
       
   204               Iterate over a copy to do this."
       
   205 
       
   206     ^ self at:aKey ifAbsent:[self at:aKey put:valueBlock value].
       
   207 
       
   208     "Created: / 16-03-2017 / 17:23:07 / stefan"
       
   209 !
       
   210 
       
   211 at:aKey ifPresent:aBlock
       
   212     "try to retrieve the value stored at aKey.
       
   213      If there is nothing stored under this key, do nothing.
       
   214      Otherwise, evaluate aBlock, passing the retrieved value as argument."
       
   215 
       
   216     |v|
       
   217 
       
   218     v := self at:aKey ifAbsent:[^ nil].
       
   219     ^ aBlock value:v.
       
   220 
       
   221     "Created: / 16-03-2017 / 17:11:27 / stefan"
       
   222 !
       
   223 
       
   224 at:aKey put:anObject
       
   225     "add the argument anObject under key, aKey to the receiver.
       
   226      Return anObject (sigh).
       
   227      WARNING: do not add elements while iterating over the receiver.
       
   228               Iterate over a copy to do this."
       
   229 
       
   230     ^ self subclassResponsibility
       
   231 
       
   232     "Created: / 16-03-2017 / 17:33:12 / stefan"
       
   233 !
       
   234 
       
   235 at:aKey put:anObject ifPresent:aBlock
       
   236     "if the receiver contains an element stored under aKey,
       
   237      retrieve it and evaluate aBlock passing the element as argument,
       
   238      return the blocks value.
       
   239      If not, store aValue under the key.
       
   240      Use this with an error-reporting block, to ensure that no keys are reused"
       
   241 
       
   242     |value isAbsent|
       
   243 
       
   244     value := self at:aKey ifAbsent:[isAbsent := true. self at:aKey put:anObject].
       
   245     isAbsent notNil ifTrue:[
       
   246         ^ value.
       
   247     ].
       
   248 
       
   249     ^ aBlock value:value.
       
   250 
       
   251     "Created: / 16-03-2017 / 17:38:00 / stefan"
       
   252 !
       
   253 
       
   254 at:aKey update:aBlock
       
   255     "update the element stored under aKey with the result from
       
   256      evaluating aBlock with the previous stored value as argument.
       
   257      Report an error if there was no such key initially.
       
   258      Return the new value stored."
       
   259 
       
   260     ^ self at:aKey put:(aBlock value:(self at:aKey))
       
   261 
       
   262     "Created: / 16-03-2017 / 17:29:22 / stefan"
       
   263 !
       
   264 
   159 keyAtEqualValue:value
   265 keyAtEqualValue:value
   160     "return the key under which value is stored.
   266     "return the key under which value is stored.
   161      Raise an error if not found.
   267      Raise an error if not found.
   162      This is a slow access, since the receiver is searched sequentially.
   268      This is a slow access, since the receiver is searched sequentially.
   163      NOTICE:
   269      NOTICE:
   213 keyAtValue:value
   319 keyAtValue:value
   214     "return the key under which value is stored.
   320     "return the key under which value is stored.
   215      Raise an error if not found.
   321      Raise an error if not found.
   216      This is a slow access, since the receiver is searched sequentially.
   322      This is a slow access, since the receiver is searched sequentially.
   217      NOTICE:
   323      NOTICE:
   218         The value is searched using identity compare.
   324         The value is searched using equality compare"
   219         use #keyAtEqualValue:ifAbsent: to compare for equality."
   325 
   220 
   326 
   221     ^ self keyAtIdenticalValue:value.
   327     ^ self keyAtEqualValue:value.
   222 
   328 
   223     "Created: / 19-06-1998 / 00:49:16 / cg"
   329     "Created: / 19-06-1998 / 00:49:16 / cg"
   224     "Modified (comment): / 07-02-2017 / 11:13:29 / cg"
   330     "Modified (comment): / 07-02-2017 / 11:13:29 / cg"
       
   331     "Modified (comment): / 16-03-2017 / 18:00:28 / stefan"
   225 !
   332 !
   226 
   333 
   227 keyAtValue:value ifAbsent:exceptionBlock
   334 keyAtValue:value ifAbsent:exceptionBlock
   228     "return the key under which value is stored.
   335     "return the key under which value is stored.
   229      If not found, return the value from evaluating exceptionBlock.
   336      If not found, return the value from evaluating exceptionBlock.
   230      This is a slow access, since the receiver is searched sequentially.
   337      This is a slow access, since the receiver is searched sequentially.
   231      NOTICE:
   338      NOTICE:
   232         The value is searched using identity compare;
   339         The value is searched using equality compare"
   233         use #keyAtEqualValue:ifAbsent: to compare for equality."
   340 
   234 
   341 
   235     ^ self keyAtIdenticalValue:value ifAbsent:exceptionBlock.
   342     ^ self keyAtEqualValue:value ifAbsent:exceptionBlock.
   236 
   343 
   237     "Created: / 19-06-1998 / 00:50:34 / cg"
   344     "Created: / 19-06-1998 / 00:50:34 / cg"
   238     "Modified: / 07-02-2017 / 11:13:20 / cg"
   345     "Modified: / 07-02-2017 / 11:13:20 / cg"
       
   346     "Modified (comment): / 16-03-2017 / 18:00:37 / stefan"
   239 !
   347 !
   240 
   348 
   241 keys
   349 keys
   242     "return a collection containing the keys of the receiver"
   350     "return a collection containing the keys of the receiver"
   243 
   351 
   259     "evaluate aBlock for each value"
   367     "evaluate aBlock for each value"
   260 
   368 
   261     self keysAndValuesDo:[:elKey :elValue | aBlock value:elValue]
   369     self keysAndValuesDo:[:elKey :elValue | aBlock value:elValue]
   262 
   370 
   263     "Created: / 19.6.1998 / 00:56:24 / cg"
   371     "Created: / 19.6.1998 / 00:56:24 / cg"
   264 !
       
   265 
       
   266 findFirstKey:aBlock
       
   267     "find and return the first key, for which evaluation of the argument, aBlock
       
   268      returns true; return nil if none is detected."
       
   269 
       
   270     self keysDo:[:key |
       
   271         (aBlock value:key) ifTrue:[^ key].
       
   272     ].
       
   273     ^ nil
       
   274 
       
   275     "Created: 8.10.1996 / 22:01:31 / cg"
       
   276     "Modified: 8.10.1996 / 22:02:03 / cg"
       
   277 !
   372 !
   278 
   373 
   279 keysAndValuesDo:aBlock
   374 keysAndValuesDo:aBlock
   280     "evaluate aBlock for each key and value"
   375     "evaluate aBlock for each key and value"
   281 
   376 
   305     ^ self subclassResponsibility
   400     ^ self subclassResponsibility
   306 
   401 
   307     "Created: / 19.6.1998 / 00:53:58 / cg"
   402     "Created: / 19.6.1998 / 00:53:58 / cg"
   308 ! !
   403 ! !
   309 
   404 
       
   405 !KeyedCollection methodsFor:'searching'!
       
   406 
       
   407 findFirst:aBlock ifNone:exceptionValue
       
   408     "find the index of the first element, for which evaluation of the argument, aBlock returns true;
       
   409      return its index or the value from exceptionValue if none detected.
       
   410      This is much like #detect:ifNone:, however, here an INDEX is returned,
       
   411      while #detect:ifNone: returns the element.
       
   412 
       
   413      Here we return the first key for which aBlock matches the value.
       
   414      Note that there is no order in a Dictionary, so any element is first."
       
   415 
       
   416     self keysAndValuesDo:[:eachKey :eachValue| (aBlock value:eachValue) ifTrue:[^ eachKey]].
       
   417     ^ exceptionValue value.
       
   418 
       
   419     "
       
   420         (KeyValueList withKeys:#('a' 'b' 'c') andValues:#('bla' 'hello' 'hallo'))
       
   421             findFirst:[:v| v first = $h].
       
   422     "
       
   423 
       
   424     "Created: / 16-03-2017 / 17:46:02 / stefan"
       
   425 !
       
   426 
       
   427 findFirstKey:aBlock
       
   428     "find and return the first key, for which evaluation of the argument, aBlock
       
   429      returns true; return nil if none is detected."
       
   430 
       
   431     self keysDo:[:key |
       
   432         (aBlock value:key) ifTrue:[^ key].
       
   433     ].
       
   434     ^ nil
       
   435 
       
   436     "Created: 8.10.1996 / 22:01:31 / cg"
       
   437     "Modified: 8.10.1996 / 22:02:03 / cg"
       
   438 ! !
       
   439 
   310 !KeyedCollection methodsFor:'testing'!
   440 !KeyedCollection methodsFor:'testing'!
   311 
   441 
   312 includesIdenticalKey:aKey
   442 includesIdenticalKey:aKey
   313     "return true, if the argument, aKey is a key in the receiver"
   443     "return true, if the argument, aKey is a key in the receiver"
   314 
   444