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 |