equal
deleted
inserted
replaced
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. |