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:[ |
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 |
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." |