Collection.st
branchjv
changeset 19478 1f5aa87f6170
parent 19331 59f77658de07
parent 19459 3bcd4f73da62
child 19610 a9a6940944a9
equal deleted inserted replaced
19477:af82888ceb72 19478:1f5aa87f6170
     1 "{ Encoding: utf8 }"
       
     2 
       
     3 "
     1 "
     4  COPYRIGHT (c) 1989 by Claus Gittinger
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     5               All Rights Reserved
     3               All Rights Reserved
     6 
     4 
     7  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
   275      Kludges around the stupid definition of OrderedCollection>>new:"
   273      Kludges around the stupid definition of OrderedCollection>>new:"
   276 
   274 
   277     ^ self newWithSize:n
   275     ^ self newWithSize:n
   278 ! !
   276 ! !
   279 
   277 
       
   278 
   280 !Collection class methodsFor:'Signal constants'!
   279 !Collection class methodsFor:'Signal constants'!
   281 
   280 
   282 emptyCollectionSignal
   281 emptyCollectionSignal
   283     "return the signal used to report non-allowed operation on empty collections"
   282     "return the signal used to report non-allowed operation on empty collections"
   284 
   283 
   331 !
   330 !
   332 
   331 
   333 isAbstract
   332 isAbstract
   334     "Return if this class is an abstract class.
   333     "Return if this class is an abstract class.
   335      True is returned for Collection here; false for subclasses.
   334      True is returned for Collection here; false for subclasses.
   336      Abstract subclasses must redefine again."
   335      Abstract subclasses must redefine this again."
   337 
   336 
   338     ^ self == Collection
   337     ^ self == Collection
   339 ! !
   338 ! !
   340 
   339 
   341 !Collection methodsFor:'Compatibility-ANSI'!
   340 !Collection methodsFor:'Compatibility-ANSI'!
   489      '' ifEmpty: [ Time now printString ]
   488      '' ifEmpty: [ Time now printString ]
   490     "
   489     "
   491 !
   490 !
   492 
   491 
   493 ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   492 ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
       
   493     "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
       
   494     
   494     |action|
   495     |action|
   495 
   496 
   496     action := self isEmpty ifTrue:[ ifEmptyValue ] ifFalse:[ ifNotEmptyValue ].
   497     action := self isEmpty ifTrue:[ ifEmptyValue ] ifFalse:[ ifNotEmptyValue ].
   497 
   498 
   498     action isBlock ifTrue:[
   499     action isBlock ifTrue:[
   502     ].
   503     ].
   503     ^ action value 
   504     ^ action value 
   504 !
   505 !
   505 
   506 
   506 ifEmpty:ifEmptyValue ifNotEmptyDo:ifNotEmptyValue
   507 ifEmpty:ifEmptyValue ifNotEmptyDo:ifNotEmptyValue
       
   508     "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
       
   509 
   507     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   510     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   508 !
   511 !
   509 
   512 
   510 ifEmptyDo:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   513 ifEmptyDo:ifEmptyValue ifNotEmpty:ifNotEmptyValue
       
   514     "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
       
   515 
   511     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   516     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   512 !
   517 !
   513 
   518 
   514 ifNotEmpty:ifNotEmptyValue
   519 ifNotEmpty:ifNotEmptyValue
       
   520     "return ifNotEmptyValue if not empty, nil otherwise"
       
   521 
   515     ^ self ifEmpty:nil ifNotEmpty:ifNotEmptyValue
   522     ^ self ifEmpty:nil ifNotEmpty:ifNotEmptyValue
   516 !
   523 !
   517 
   524 
   518 ifNotEmptyDo:ifNotEmptyValue
   525 ifNotEmptyDo:ifNotEmptyValue
       
   526     "return ifNotEmptyValue if not empty, nil otherwise"
       
   527 
   519     ^ self ifEmpty:nil ifNotEmpty:ifNotEmptyValue
   528     ^ self ifEmpty:nil ifNotEmpty:ifNotEmptyValue
   520 !
   529 !
   521 
   530 
   522 ifNotEmptyDo:ifNotEmptyValue ifEmpty:ifEmptyValue
   531 ifNotEmptyDo:ifNotEmptyValue ifEmpty:ifEmptyValue
       
   532     "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
       
   533 
   523     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   534     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
   524 !
   535 !
   525 
   536 
   526 intersection:aCollection
   537 intersection:aCollection
       
   538     "same as intersect: for Squeak compatibility"
       
   539     
   527     ^ self intersect:aCollection
   540     ^ self intersect:aCollection
   528 
   541 
   529     "Created: / 22-10-2008 / 21:29:27 / cg"
   542     "Created: / 22-10-2008 / 21:29:27 / cg"
   530 ! !
   543 ! !
       
   544 
   531 
   545 
   532 !Collection methodsFor:'accessing'!
   546 !Collection methodsFor:'accessing'!
   533 
   547 
   534 anElement
   548 anElement
   535     "return any element from the collection, 
   549     "return any element from the collection, 
  1111      (see also: #removeAllFoundIn:, which does not raise an error).
  1125      (see also: #removeAllFoundIn:, which does not raise an error).
  1112 
  1126 
  1113      Notice: for some collections (those not tuned for
  1127      Notice: for some collections (those not tuned for
  1114              resizing themself) this may be very slow.
  1128              resizing themself) this may be very slow.
  1115              If the number of removed elements is big compared to to
  1129              If the number of removed elements is big compared to to
  1116              the receivers size, it may be better to copy the
  1130              the receiver's size, it may be better to copy the
  1117              ones which are not to be removed into a new collection."
  1131              ones which are not to be removed into a new collection."
  1118 
  1132 
  1119     aCollection do:[:element | self remove:element].
  1133     aCollection do:[:element | self remove:element].
  1120     ^ aCollection
  1134     ^ aCollection
  1121 
  1135 
  1180      (see also: #removeAllFoundIn:, which does not raise an error).
  1194      (see also: #removeAllFoundIn:, which does not raise an error).
  1181 
  1195 
  1182      Notice: for some collections (those not tuned for
  1196      Notice: for some collections (those not tuned for
  1183              resizing themself) this may be very slow.
  1197              resizing themself) this may be very slow.
  1184              If the number of removed elements is big compared to to
  1198              If the number of removed elements is big compared to to
  1185              the receivers size, it may be better to copy the
  1199              the receiver's size, it may be better to copy the
  1186              ones which are not to be removed into a new collection."
  1200              ones which are not to be removed into a new collection."
  1187 
  1201 
  1188     aCollection do:[:element | self removeIdentical:element].
  1202     aCollection do:[:element | self removeIdentical:element].
  1189     ^ aCollection
  1203     ^ aCollection
  1190 
  1204 
  2615     "Modified: / 13-09-2006 / 11:17:42 / cg"
  2629     "Modified: / 13-09-2006 / 11:17:42 / cg"
  2616 !
  2630 !
  2617 
  2631 
  2618 detect:checkBlock thenCompute:evalBlock 
  2632 detect:checkBlock thenCompute:evalBlock 
  2619     "evaluate the argument, aBlock for each element in the receiver until
  2633     "evaluate the argument, aBlock for each element in the receiver until
  2620      chloeckBck returns true; in this case return the value from evalBlock
  2634      checkBck returns true; in this case return the value from evalBlock
  2621      applied to the element which caused the true evaluation.
  2635      applied to the element which caused the true evaluation.
  2622      If none of the evaluations returns true, report an error"
  2636      If none of the evaluations returns true, report an error"
  2623 
  2637 
  2624     ^ self detect:checkBlock thenCompute:evalBlock ifNone:[self errorNotFound]
  2638     ^ self detect:checkBlock thenCompute:evalBlock ifNone:[self errorNotFound]
  2625 
  2639 
  2629     "
  2643     "
  2630 !
  2644 !
  2631 
  2645 
  2632 detect:checkBlock thenCompute:evalBlock ifNone:exceptionValue
  2646 detect:checkBlock thenCompute:evalBlock ifNone:exceptionValue
  2633     "evaluate the argument, aBlock for each element in the receiver until
  2647     "evaluate the argument, aBlock for each element in the receiver until
  2634      chloeckBck returns true; in this case return the value from evalBlock
  2648      checkBck returns true; in this case return the value from evalBlock
  2635      applied to the element which caused the true evaluation.
  2649      applied to the element which caused the true evaluation.
  2636      If none of the evaluations returns true, return the value from exceptionValue."
  2650      If none of the evaluations returns true, return the value from exceptionValue."
  2637 
  2651 
  2638     ^ evalBlock value:(self detect:checkBlock ifNone:[^ exceptionValue value]).
  2652     ^ evalBlock value:(self detect:checkBlock ifNone:[^ exceptionValue value]).
  2639 
  2653 
  2680     "
  2694     "
  2681 !
  2695 !
  2682 
  2696 
  2683 detectMax: aBlock
  2697 detectMax: aBlock
  2684     "Evaluate aBlock with each of the receiver's elements as the argument. 
  2698     "Evaluate aBlock with each of the receiver's elements as the argument. 
  2685     Answer the element for which aBlock evaluates to the highest magnitude.
  2699      Answer the element for which aBlock evaluates to the highest magnitude.
  2686     If the receiver collection is empty, return nil.  
  2700      If the receiver collection is empty, return nil.  
  2687     This method might also be called elect:."
  2701      This method might also be called elect:."
  2688 
  2702 
  2689     | maxElement maxValue |
  2703     | maxElement maxValue |
  2690 
  2704 
  2691     self do: [:each | 
  2705     self do: [:each | 
  2692         | val |
  2706         | val |
  2693 
  2707 
  2694         val := aBlock value: each.
  2708         val := aBlock value: each.
  2695         "Note that there is no way to get the first element that works 
  2709         "Note that there is no way to get the first element 
  2696         for all kinds of Collections.  
  2710          which works for all kinds of Collections.  
  2697         Must test every one (maxValue is nil for the first element)."
  2711          Must therefore test every one (maxValue is nil for the first element)."
  2698         (maxValue == nil or:[val > maxValue]) ifTrue: [
  2712         (maxValue == nil or:[val > maxValue]) ifTrue: [
  2699            maxElement := each.
  2713            maxElement := each.
  2700            maxValue := val
  2714            maxValue := val
  2701         ]
  2715         ]
  2702     ].
  2716     ].
  2709     "Created: / 20-08-2011 / 21:34:49 / cg"
  2723     "Created: / 20-08-2011 / 21:34:49 / cg"
  2710 !
  2724 !
  2711 
  2725 
  2712 detectMin: aBlock
  2726 detectMin: aBlock
  2713     "Evaluate aBlock with each of the receiver's elements as the argument. 
  2727     "Evaluate aBlock with each of the receiver's elements as the argument. 
  2714     Answer the element for which aBlock evaluates to the lowest number.
  2728      Answer the element for which aBlock evaluates to the lowest number.
  2715     If the receiver collection is empty, return nil."
  2729      If the receiver collection is empty, return nil."
  2716 
  2730 
  2717     | minElement minValue |
  2731     | minElement minValue |
  2718 
  2732 
  2719     self do: [:each | 
  2733     self do: [:each | 
  2720         | val |
  2734         | val |
  2721 
  2735 
  2722         val := aBlock value: each.
  2736         val := aBlock value: each.
  2723         "Note that there is no way to get the first element that works 
  2737         "Note that there is no way to get the first element 
  2724         for all kinds of Collections.  
  2738          which works for all kinds of Collections.  
  2725         Must test every one (maxValue is nil for the first element)."
  2739          Must therefore test every one (minValue is nil for the first element)."
  2726         (minValue == nil or:[val < minValue]) ifTrue: [
  2740         (minValue == nil or:[val < minValue]) ifTrue: [
  2727            minElement := each.
  2741            minElement := each.
  2728            minValue := val
  2742            minValue := val
  2729         ]
  2743         ]
  2730     ].
  2744     ].
  2853 doWhileTrue:aBlock
  2867 doWhileTrue:aBlock
  2854     "evaluate the argument, aBlock for each element,
  2868     "evaluate the argument, aBlock for each element,
  2855      until the block evaluates to false.
  2869      until the block evaluates to false.
  2856      Answer true, if all the elements have been processed,
  2870      Answer true, if all the elements have been processed,
  2857      false otherwise."
  2871      false otherwise."
  2858 
       
  2859 
  2872 
  2860     self do:[:el |
  2873     self do:[:el |
  2861         (aBlock value:el) ifFalse:[
  2874         (aBlock value:el) ifFalse:[
  2862             ^ false.
  2875             ^ false.
  2863         ]
  2876         ]
  3176     "Modified: 20.4.1996 / 11:33:50 / cg"
  3189     "Modified: 20.4.1996 / 11:33:50 / cg"
  3177 !
  3190 !
  3178 
  3191 
  3179 keysAndValuesDo:aTwoArgBlock
  3192 keysAndValuesDo:aTwoArgBlock
  3180     "evaluate the argument, aBlock for every element in the collection,
  3193     "evaluate the argument, aBlock for every element in the collection,
  3181      passing both index and element as arguments."
  3194      passing both index and element as arguments.
       
  3195      Blocked here - must be redefined in subclasses which have keyed elements"
  3182 
  3196 
  3183     ^ self errorNotKeyed
  3197     ^ self errorNotKeyed
  3184 !
  3198 !
  3185 
  3199 
  3186 keysAndValuesReverseDo:aTwoArgBlock
  3200 keysAndValuesReverseDo:aTwoArgBlock
  3187     "evaluate the argument, aBlock in reverse order for every element in the collection,
  3201     "evaluate the argument, aBlock in reverse order for every element in the collection,
  3188      passing both index and element as arguments."
  3202      passing both index and element as arguments.
       
  3203      Blocked here - must be redefined in subclasses which have keyed elements"
  3189 
  3204 
  3190     ^ self errorNotKeyed
  3205     ^ self errorNotKeyed
  3191 
  3206 
  3192     "Created: 9.5.1996 / 00:58:24 / cg"
  3207     "Created: 9.5.1996 / 00:58:24 / cg"
  3193 !
  3208 !
  3194 
  3209 
  3195 keysAndValuesSelect:selectBlockWith2Args thenCollect:collectBlockWith2Args
  3210 keysAndValuesSelect:selectBlockWith2Args thenCollect:collectBlockWith2Args
       
  3211     "first call the selectBlockWith2Args, passsing it each key and element,
       
  3212      if that returns true, call the collectBlockWith2Args, also with key and element,
       
  3213      and collect the resulting values in an OrderedCollection."
       
  3214     
  3196     |collected|
  3215     |collected|
  3197 
  3216 
  3198     collected := OrderedCollection new.
  3217     collected := OrderedCollection new.
  3199     self keysAndValuesDo:[:eachKey :eachValue |
  3218     self keysAndValuesDo:[:eachKey :eachValue |
  3200         (selectBlockWith2Args value:eachKey value:eachValue) ifTrue:[
  3219         (selectBlockWith2Args value:eachKey value:eachValue) ifTrue:[
  3202         ].
  3221         ].
  3203     ].
  3222     ].
  3204     ^ collected
  3223     ^ collected
  3205 
  3224 
  3206     "
  3225     "
  3207      #(10 20 30 40) keysAndValuesSelect:[:idx :val | idx > 2] thenCollect:[:idx :val | idx->val]
  3226      #(10 20 30 40) 
       
  3227         keysAndValuesSelect:[:idx :val | idx > 2] 
       
  3228         thenCollect:[:idx :val | idx->val]
  3208     "
  3229     "
  3209 !
  3230 !
  3210 
  3231 
  3211 keysDo:aBlock
  3232 keysDo:aBlock
  3212     "evaluate the argument, aBlock for every key in the collection."
  3233     "evaluate the argument, aBlock for every key in the collection."
  3532 
  3553 
  3533     "Created: / 07-08-2010 / 16:26:15 / cg"
  3554     "Created: / 07-08-2010 / 16:26:15 / cg"
  3534 !
  3555 !
  3535 
  3556 
  3536 select:selectBlock thenDo:doBlock
  3557 select:selectBlock thenDo:doBlock
  3537     "combination of select followed by do
  3558     "combination of select followed by do.
  3538      The same as if two separate select:+do: messages were sent,
  3559      The same as if two separate select:+do: messages were sent,
  3539      but avoids the creation of intermediate collections, 
  3560      but avoids the creation of intermediate collections, 
  3540      so this is nicer for big collections."
  3561      so this is nicer for big collections."
  3541 
  3562 
  3542     self do:[:eachElement |
  3563     self do:[:eachElement |
  3545         ]
  3566         ]
  3546     ].
  3567     ].
  3547 
  3568 
  3548     "
  3569     "
  3549      #(1 2 3 4 5 6 7) select:[:i | i even] thenDo:[:i | Transcript showCR:i]
  3570      #(1 2 3 4 5 6 7) select:[:i | i even] thenDo:[:i | Transcript showCR:i]
       
  3571     "
       
  3572 !
       
  3573 
       
  3574 selectWithIndex:aTwoArgBlock
       
  3575     "return a new collection with all elements from the receiver, 
       
  3576      for which the argument aBlock evaluates to true.
       
  3577      aTwoArgBlock is called with value and index as arguments."
       
  3578 
       
  3579     |newCollection|
       
  3580 
       
  3581     newCollection := self species new.
       
  3582     self doWithIndex:[:eachValue :eachKey |
       
  3583         (aTwoArgBlock value:eachValue value:eachKey) ifTrue:[newCollection add:eachValue].
       
  3584     ].
       
  3585     ^ newCollection
       
  3586 
       
  3587     "
       
  3588      #(10 20 30 40) selectWithIndex:[:e :i | i odd]   
       
  3589      #(10 20 30 40) selectWithIndex:[:e :i | i even]   
  3550     "
  3590     "
  3551 !
  3591 !
  3552 
  3592 
  3553 triplesDo:aThreeArgBlock
  3593 triplesDo:aThreeArgBlock
  3554     "evaluate the argument, aThreeArgBlock for every element in the collection,
  3594     "evaluate the argument, aThreeArgBlock for every element in the collection,
  4197         aStream nextPutAll:(s contents).
  4237         aStream nextPutAll:(s contents).
  4198     ].
  4238     ].
  4199     aStream nextPut:$)
  4239     aStream nextPut:$)
  4200 
  4240 
  4201     "
  4241     "
  4202      #(1 2 3 'hello' $a $ü) printOn:Transcript
  4242      #(1 2 3 'hello' $a $ü) printOn:Transcript
  4203      (Array new:100000) printOn:Transcript
  4243      (Array new:100000) printOn:Transcript
  4204      (Array new:100000) printOn:Stdout          
  4244      (Array new:100000) printOn:Stdout          
  4205      (Array new:100000) printString size 
  4245      (Array new:100000) printString size 
  4206      (Dictionary new at:#hello put:'world'; 
  4246      (Dictionary new at:#hello put:'world'; 
  4207                      at:#foo put:'bar'; yourself) printOn:Transcript
  4247                      at:#foo put:'bar'; yourself) printOn:Transcript
  4300 defaultElement
  4340 defaultElement
  4301     ^  nil
  4341     ^  nil
  4302 !
  4342 !
  4303 
  4343 
  4304 isReadOnly
  4344 isReadOnly
       
  4345     "true if this is a readOnly (immutable) collection.
       
  4346      Q1: should this be called isImmutable?
       
  4347      Q2: who uses this?"
       
  4348     
  4305     ^ false
  4349     ^ false
  4306 !
  4350 !
  4307 
  4351 
  4308 isWritable
  4352 isWritable
       
  4353     "true if this is not a readOnly (immutable) collection.
       
  4354      Q1: should this be called isMutable?
       
  4355      Q2: who uses this?"
       
  4356 
  4309     ^ self isReadOnly not
  4357     ^ self isReadOnly not
  4310 !
  4358 !
  4311 
  4359 
  4312 size
  4360 size
  4313     "return the number of elements in the receiver.
  4361     "return the number of elements in the receiver.
  5527 !
  5575 !
  5528 
  5576 
  5529 includesAll:aCollection
  5577 includesAll:aCollection
  5530     "return true, if the the receiver includes all elements of
  5578     "return true, if the the receiver includes all elements of
  5531      the argument, aCollection; false if any is missing.
  5579      the argument, aCollection; false if any is missing.
  5532      Notice: this method has O-square runtime behavior and may be
  5580      Notice: this method has O² runtime behavior and may be
  5533              slow for big receivers/args. 
  5581              slow for big receivers/args. 
  5534              Think about using a Set, or Dictionary."
  5582              Think about using a Set, or Dictionary."
  5535 
  5583 
  5536     ^ aCollection conform:[:element | (self includes:element)]
  5584     ^ aCollection conform:[:element | (self includes:element)]
  5537 
  5585 
  5546 
  5594 
  5547 includesAny:searchCollection
  5595 includesAny:searchCollection
  5548     "return true, if the the receiver includes any elements of
  5596     "return true, if the the receiver includes any elements of
  5549      the argument, aCollection; false if it includes none.
  5597      the argument, aCollection; false if it includes none.
  5550      Notice: 
  5598      Notice: 
  5551         this method has O^2(N) runtime behavior and may be
  5599         this method has O² runtime behavior and may be
  5552         slow for big receivers/args. 
  5600         slow for big receivers/args. 
  5553         Think about using a Set or Dictionary. 
  5601         Think about using a Set or Dictionary. 
  5554         Some speedup is also possible, by arranging highly
  5602         Some speedup is also possible, by arranging highly
  5555         probable elements towards the beginning of aCollection,
  5603         probable elements towards the beginning of aCollection,
  5556         to avoid useless searches.
  5604         to avoid useless searches.
  5610 
  5658 
  5611 includesAnyIdentical:aCollection
  5659 includesAnyIdentical:aCollection
  5612     "return true, if the the receiver includes any elements of
  5660     "return true, if the the receiver includes any elements of
  5613      the argument, aCollection; false if it includes none.
  5661      the argument, aCollection; false if it includes none.
  5614      Use identity compare for comparing.
  5662      Use identity compare for comparing.
  5615      Notice: this method has O^2(N) runtime behavior and may be
  5663      Notice: this method has O² runtime behavior and may be
  5616              slow for big receivers/args. 
  5664              slow for big receivers/args. 
  5617              Think about using a Set or Dictionary. 
  5665              Think about using a Set or Dictionary. 
  5618              Some speedup is also possible, by arranging highly
  5666              Some speedup is also possible, by arranging highly
  5619              probable elements towards the beginning of aCollection,
  5667              probable elements towards the beginning of aCollection,
  5620              to avoid useless searches."
  5668              to avoid useless searches."