1270 "negated value of all elements in the collection" |
1270 "negated value of all elements in the collection" |
1271 |
1271 |
1272 ^ self collect:[:a | a negated] |
1272 ^ self collect:[:a | a negated] |
1273 |
1273 |
1274 " |
1274 " |
1275 TestCase assert:( { 1. -2. -3. 4 } negated = { -1. 2. 3. -4 }). |
1275 TestCase assert:( #(1 -2 -3 4) negated = #(-1 2 3 -4)). |
1276 " |
1276 " |
1277 |
1277 |
1278 "Modified: / 18-03-2011 / 10:33:53 / cg" |
1278 "Modified: / 18-03-2011 / 10:33:53 / cg" |
1279 ! |
1279 ! |
1280 |
1280 |
1281 product |
1281 product |
1282 "multiply up all elements." |
1282 "multiply up all elements." |
1283 |
1283 |
1284 self emptyCheck. |
|
1285 ^ self |
1284 ^ self |
1286 inject:(self first class unity) |
1285 fold:[:accum :each | accum * each]. |
1287 into:[:accum :each | accum * each]. |
1286 |
1288 |
1287 " |
1289 " |
1288 TestCase should:[ Array new product ] raise:Error. |
1290 TestCase should:[ Array new sum ] raise:Error. |
1289 |
1291 |
1290 TestCase assert:( #(1) product == 1). |
1292 TestCase assert:( { 1 } product == 1). |
1291 TestCase assert:( #(6) product == 6). |
1293 TestCase assert:( { 6 } product == 6). |
1292 TestCase assert:( #(1 2 3 4 5) product = 5 factorial ) |
1294 TestCase assert:( { 1. 2. 3. 4. 5. } product = 5 factorial ) |
|
1295 " |
1293 " |
1296 ! |
1294 ! |
1297 |
1295 |
1298 sum |
1296 sum |
1299 "sum up all elements; return 0 for an empty collection." |
1297 "sum up all elements; return 0 for an empty collection." |
1300 |
1298 |
1301 self isEmpty ifTrue:[^ 0]. |
1299 self isEmpty ifTrue:[^ 0]. |
1302 |
1300 |
1303 ^ self |
1301 ^ self |
1304 inject:(self first class zero) |
1302 fold:[:accum :each | accum + each]. |
1305 into:[:accum :each | accum + each]. |
1303 |
1306 |
1304 " |
1307 |
1305 TestCase assert: ( #() sum = 0 ). |
1308 " |
1306 TestCase assert: ( #(1) sum = 1 ). |
1309 TestCase assert: ( { } sum = 0 ). |
1307 TestCase assert: ( #(1 2 3 4) sum = 10 ). |
1310 TestCase assert: ( { 1 } sum = 1 ). |
|
1311 TestCase assert: ( { 1. 2. 3. 4. } sum = 10 ). |
|
1312 TestCase assert: ( (1 to:10) sum = 55 ). |
1308 TestCase assert: ( (1 to:10) sum = 55 ). |
1313 TestCase assert: ( 'abc' asByteArray sum = 294 ). |
1309 TestCase assert: ( 'abc' asByteArray sum = 294 ). |
1314 TestCase assert: ( { 10 +/- 2. |
1310 TestCase assert: ( { 10 +/- 2. |
1315 20 +/- 4. |
1311 20 +/- 4. |
1316 100 +/- 10 } sum = (130 +/- 16) ). |
1312 100 +/- 10 } sum = (130 +/- 16) ). |
2398 "Evaluate the block with the first two elements of the receiver, |
2395 "Evaluate the block with the first two elements of the receiver, |
2399 then with the result of the first evaluation and the next element, |
2396 then with the result of the first evaluation and the next element, |
2400 and so on. Answer the result of the final evaluation. If the receiver |
2397 and so on. Answer the result of the final evaluation. If the receiver |
2401 is empty, raise an error. If the receiver has a single element, answer |
2398 is empty, raise an error. If the receiver has a single element, answer |
2402 that element. |
2399 that element. |
2403 See also: inject:into:" |
2400 |
|
2401 Here the reduction is done from left to right. |
|
2402 |
|
2403 See also: #inject:into: #reduce:" |
2404 |
2404 |
2405 | first nextValue | |
2405 | first nextValue | |
2406 |
|
2407 self emptyCheck. |
|
2408 |
2406 |
2409 first := true. |
2407 first := true. |
2410 self do:[:each | |
2408 self do:[:each | |
2411 nextValue := first |
2409 first |
2412 ifTrue: [first := false. each] |
2410 ifTrue: [first := false. nextValue := each] |
2413 ifFalse: [binaryBlock value: nextValue value: each] |
2411 ifFalse: [nextValue := binaryBlock value:nextValue value:each] |
|
2412 ]. |
|
2413 first ifTrue:[ |
|
2414 ^ self emptyCollectionError. |
2414 ]. |
2415 ]. |
2415 ^ nextValue |
2416 ^ nextValue |
2416 |
2417 |
2417 " |
2418 " |
|
2419 (1 to:15) fold:[:x :y| '(', x printString, '+', y printString, ')'] |
|
2420 (1 to:15) reduce:[:x :y| '(', x printString, '+', y printString, ')'] |
2418 #('if' 'it' 'is' 'to' 'be' 'it' 'is' 'up' 'to' 'me') fold: [:a :b | a, ' ', b] |
2421 #('if' 'it' 'is' 'to' 'be' 'it' 'is' 'up' 'to' 'me') fold: [:a :b | a, ' ', b] |
|
2422 #('if' 'it' 'is' 'to' 'be' 'it' 'is' 'up' 'to' 'me') reduce: [:a :b | a, ' ', b] |
2419 " |
2423 " |
2420 |
2424 |
2421 "Created: / 14-09-2011 / 16:29:53 / cg" |
2425 "Created: / 14-09-2011 / 16:29:53 / cg" |
2422 ! |
2426 ! |
2423 |
2427 |
2424 inject:thisValue into:binaryBlock |
2428 inject:thisValue into:binaryBlock |
2425 "starting with thisValue for value, pass this value and each element |
2429 "starting with thisValue for value, pass this value and each element |
2426 to binaryBlock, replacing value with the result returned from the block |
2430 to binaryBlock, replacing value with the result returned from the block |
2427 in the next iteration." |
2431 in the next iteration. |
|
2432 |
|
2433 See also: #fold: #reduce:" |
2428 |
2434 |
2429 |nextValue| |
2435 |nextValue| |
2430 |
2436 |
2431 nextValue := thisValue. |
2437 nextValue := thisValue. |
2432 self do: [:each | nextValue := binaryBlock value:nextValue value:each]. |
2438 self do: [:each | nextValue := binaryBlock value:nextValue value:each]. |
2621 " |
2627 " |
2622 |
2628 |
2623 "Created: / 20-07-2011 / 00:54:41 / cg" |
2629 "Created: / 20-07-2011 / 00:54:41 / cg" |
2624 ! |
2630 ! |
2625 |
2631 |
2626 reduce:aTwoArgBlock |
2632 reduce:binaryBlock |
2627 "reduce by iteratively applying aTwoArgBlock to the result from the |
2633 "Evaluate the block with the first two elements of the receiver, |
2628 previous reduce and an element. |
2634 then with the result of the first evaluation and the next element, |
2629 The first evaluation is on the first two elements." |
2635 and so on. Answer the result of the final evaluation. If the receiver |
2630 |
2636 is empty, raise an error. If the receiver has a single element, answer |
2631 |first| |
2637 that element. |
2632 |
2638 |
2633 self emptyCheck. |
2639 Here the reduction is done from right to left. |
|
2640 |
|
2641 See also: #inject:into: #fold:" |
|
2642 |
|
2643 | first nextValue | |
|
2644 |
2634 first := true. |
2645 first := true. |
2635 ^ self |
2646 self do:[:each | |
2636 inject:nil |
2647 first |
2637 into:[:accu :el | |
2648 ifTrue: [first := false. nextValue := each] |
2638 first ifTrue:[ |
2649 ifFalse: [nextValue := binaryBlock value:each value:nextValue] |
2639 first := false. |
2650 ]. |
2640 el |
2651 first ifTrue:[ |
2641 ] ifFalse:[ |
2652 ^ self emptyCollectionError. |
2642 aTwoArgBlock value:el value:accu |
2653 ]. |
2643 ] |
2654 ^ nextValue |
2644 ] |
2655 |
2645 |
2656 " |
2646 " |
2657 (1 to:15) reduce:[:x :y| '(', x printString, '+', y printString, ')'] |
|
2658 (1 to:15) fold:[:x :y| '(', x printString, '+', y printString, ')'] |
|
2659 #('if' 'it' 'is' 'to' 'be' 'it' 'is' 'up' 'to' 'me') reduce: [:a :b | a, ' ', b] |
|
2660 #('if' 'it' 'is' 'to' 'be' 'it' 'is' 'up' 'to' 'me') fold: [:a :b | a, ' ', b] |
2647 #(10 1 2 3) reduce:[:el :diff | diff - el] |
2661 #(10 1 2 3) reduce:[:el :diff | diff - el] |
2648 #(10 1 2 3) reduce:[:el :diff | diff + el] |
2662 #(10 1 2 3) reduce:[:el :diff | diff + el] |
2649 " |
2663 " |
2650 |
2664 |
2651 "Created: / 28-02-2012 / 21:16:33 / cg" |
2665 "Created: / 28-02-2012 / 21:16:33 / cg" |
2652 ! |
2666 ! |
2653 |
2667 |
2654 reduceLeft:aTwoArgBlock |
2668 reduceLeft:aTwoArgBlock |
2655 "reduce by iteratively applying aTwoArgBlock to an element and the result from the |
2669 ^ self fold:aTwoArgBlock |
2656 previous reduce. The first evaluation is on the first two elements." |
|
2657 |
|
2658 |first| |
|
2659 |
|
2660 self emptyCheck. |
|
2661 first := true. |
|
2662 ^ self |
|
2663 inject:nil |
|
2664 into:[:accu :el | |
|
2665 first ifTrue:[ |
|
2666 first := false. |
|
2667 el |
|
2668 ] ifFalse:[ |
|
2669 aTwoArgBlock value:accu value:el |
|
2670 ] |
|
2671 ] |
|
2672 |
2670 |
2673 " |
2671 " |
2674 #(1 2 3 4 5) reduceLeft:[:sum :el | sum + el] |
2672 #(1 2 3 4 5) reduceLeft:[:sum :el | sum + el] |
2675 " |
2673 " |
2676 |
2674 |
2809 (5 five #'fuenf') |
2807 (5 five #'fuenf') |
2810 (6 six sechs) |
2808 (6 six sechs) |
2811 ) |
2809 ) |
2812 triplesDo:[:num :sym1 :sym2 | |
2810 triplesDo:[:num :sym1 :sym2 | |
2813 Transcript show:num; space; show:sym1; space; showCR:sym2 |
2811 Transcript show:num; space; show:sym1; space; showCR:sym2 |
|
2812 ] |
|
2813 " |
|
2814 |
|
2815 "Modified: 10.5.1997 / 14:15:43 / cg" |
|
2816 ! |
|
2817 |
|
2818 tuplesDo:aBlock |
|
2819 "evaluate the argument, aBlock for every element in the collection, |
|
2820 which is supposed to consist of N-element collections. |
|
2821 The block is called with N arguments for each collection in the receiver." |
|
2822 |
|
2823 self do:[:aTuple | |
|
2824 aBlock valueWithArguments:aTuple |
|
2825 ] |
|
2826 " |
|
2827 #( |
|
2828 (1 one eins uno) |
|
2829 (2 two zwei due) |
|
2830 (3 three drei tre) |
|
2831 (4 four vier quattro) |
|
2832 (5 five #'fuenf' cinque) |
|
2833 ) |
|
2834 tuplesDo:[:num :sym1 :sym2 :sym3 | |
|
2835 Transcript show:num; space; show:sym1; space; show:sym2; space; showCR:sym3 |
2814 ] |
2836 ] |
2815 " |
2837 " |
2816 |
2838 |
2817 "Modified: 10.5.1997 / 14:15:43 / cg" |
2839 "Modified: 10.5.1997 / 14:15:43 / cg" |
2818 ! |
2840 ! |
3067 ! ! |
3089 ! ! |
3068 |
3090 |
3069 !Collection methodsFor:'error handling'! |
3091 !Collection methodsFor:'error handling'! |
3070 |
3092 |
3071 emptyCheck |
3093 emptyCheck |
3072 "check if the receiver is empty; report an error if so" |
3094 "check if the receiver is empty; report an error if so. |
|
3095 |
|
3096 CAVEAT: Set redefines #emptySet with a different meaning, |
|
3097 so calling this for a Set or a Dictionary does not show the |
|
3098 expected behaviour!!" |
3073 |
3099 |
3074 self isEmpty ifTrue:[ |
3100 self isEmpty ifTrue:[ |
3075 ^ self emptyCollectionError. |
3101 ^ self emptyCollectionError. |
3076 ]. |
3102 ]. |
3077 ! |
3103 ! |
3659 max |
3685 max |
3660 "return the maximum value in the receiver collection, |
3686 "return the maximum value in the receiver collection, |
3661 using #< to compare elements. |
3687 using #< to compare elements. |
3662 Raises an error, if the receiver is empty." |
3688 Raises an error, if the receiver is empty." |
3663 |
3689 |
3664 self emptyCheck. |
|
3665 |
|
3666 ^ self |
3690 ^ self |
3667 inject:nil |
3691 fold:[:maxSoFar :each | |
3668 into:[:maxSoFar :this | |
3692 maxSoFar < each |
3669 (maxSoFar isNil or:[maxSoFar < this]) |
3693 ifTrue:[each] |
3670 ifTrue:[this] |
|
3671 ifFalse:[maxSoFar] |
3694 ifFalse:[maxSoFar] |
3672 ] |
3695 ] |
3673 |
3696 |
3674 " |
3697 " |
3675 #(15 1 -9 10 5) max |
3698 #(15 1 -9 10 5) max |
3685 maxApplying:aBlock |
3708 maxApplying:aBlock |
3686 "return the maximum value from applying aBlock to each element in the receiver collection, |
3709 "return the maximum value from applying aBlock to each element in the receiver collection, |
3687 using aBlock to compare elements. |
3710 using aBlock to compare elements. |
3688 Raises an error, if the receiver is empty." |
3711 Raises an error, if the receiver is empty." |
3689 |
3712 |
3690 self emptyCheck. |
3713 |ret| |
3691 |
3714 |
3692 ^ self |
3715 ret := self |
3693 inject:nil |
3716 inject:nil |
3694 into:[:maxSoFar :this | |
3717 into:[:maxSoFar :this | |
3695 |v| |
3718 |v| |
3696 |
3719 |
3697 v := aBlock value:this. |
3720 v := aBlock value:this. |
3698 (maxSoFar isNil or:[maxSoFar < v]) |
3721 (maxSoFar isNil or:[maxSoFar < v]) |
3699 ifTrue:[v] |
3722 ifTrue:[v] |
3700 ifFalse:[maxSoFar] |
3723 ifFalse:[maxSoFar] |
3701 ] |
3724 ]. |
3702 |
3725 |
3703 " |
3726 ret isNil ifTrue:[ |
|
3727 ^ self emptyCollectionError. |
|
3728 ]. |
|
3729 ^ ret. |
|
3730 |
|
3731 " |
|
3732 #() max -> Error |
3704 #(15 1 -9 -20 10 5) max -> 15 |
3733 #(15 1 -9 -20 10 5) max -> 15 |
3705 #(15 1 -9 -20 10 5) maxApplying:[:el | el abs] -> 20 |
3734 #(15 1 -9 -20 10 5) maxApplying:[:el | el abs] -> 20 |
3706 " |
3735 " |
3707 |
3736 |
3708 "Created: / 23-08-2010 / 11:02:50 / cg" |
3737 "Created: / 23-08-2010 / 11:02:50 / cg" |
3712 min |
3741 min |
3713 "return the minimum value in the receiver collection, |
3742 "return the minimum value in the receiver collection, |
3714 using < to compare elements. |
3743 using < to compare elements. |
3715 Raises an error, if the receiver is empty." |
3744 Raises an error, if the receiver is empty." |
3716 |
3745 |
3717 self emptyCheck. |
|
3718 |
|
3719 ^ self |
3746 ^ self |
3720 inject:nil |
3747 fold:[:minSoFar :each | |
3721 into:[:minSoFar :this | |
3748 each < minSoFar |
3722 (minSoFar isNil or:[this < minSoFar]) |
3749 ifTrue:[each] |
3723 ifTrue:[this] |
|
3724 ifFalse:[minSoFar] |
3750 ifFalse:[minSoFar] |
3725 ] |
3751 ] |
3726 |
3752 |
3727 " |
3753 " |
3728 #(15 1 -9 10 5) min |
3754 #(15 1 -9 10 5) min |
3737 minApplying:aBlock |
3763 minApplying:aBlock |
3738 "return the minimum value from applying aBlock to each element in the receiver collection, |
3764 "return the minimum value from applying aBlock to each element in the receiver collection, |
3739 using aBlock to compare elements. |
3765 using aBlock to compare elements. |
3740 Raises an error, if the receiver is empty." |
3766 Raises an error, if the receiver is empty." |
3741 |
3767 |
3742 self emptyCheck. |
3768 |ret| |
3743 |
3769 |
3744 ^ self |
3770 ret := self |
3745 inject:nil |
3771 inject:nil |
3746 into:[:minSoFar :this | |
3772 into:[:minSoFar :this | |
3747 |v| |
3773 |v| |
3748 |
3774 |
3749 v := aBlock value:this. |
3775 v := aBlock value:this. |
3750 (minSoFar isNil or:[v < minSoFar]) |
3776 (minSoFar isNil or:[v < minSoFar]) |
3751 ifTrue:[v] |
3777 ifTrue:[v] |
3752 ifFalse:[minSoFar] |
3778 ifFalse:[minSoFar] |
3753 ] |
3779 ]. |
|
3780 ret isNil ifTrue:[ |
|
3781 ^ self emptyCollectionError. |
|
3782 ]. |
|
3783 ^ ret. |
3754 |
3784 |
3755 " |
3785 " |
3756 #(15 -1 -9 10 5) min -> -9 |
3786 #(15 -1 -9 10 5) min -> -9 |
3757 #(15 -1 -9 10 5) minApplying:[:el | el abs] -> 1 |
3787 #(15 -1 -9 10 5) minApplying:[:el | el abs] -> 1 |
3758 " |
3788 " |
3856 m := self arithmeticMean. |
3888 m := self arithmeticMean. |
3857 sumDeltaSquares := self inject:0 into:[:sum :this | sum + ((this - m) squared)]. |
3889 sumDeltaSquares := self inject:0 into:[:sum :this | sum + ((this - m) squared)]. |
3858 ^ (sumDeltaSquares / (self size - 1)) sqrt |
3890 ^ (sumDeltaSquares / (self size - 1)) sqrt |
3859 |
3891 |
3860 " |
3892 " |
3861 TestCase assert:( { 1. 2. 3. 4 } arithmeticMean = 2.5). |
3893 TestCase assert:( #( 1 2 3 4) arithmeticMean = 2.5). |
3862 TestCase assert:( { 13. 23. 12. 44. 55 } arithmeticMean closeTo: 29.4). |
3894 TestCase assert:( #(13 23 12 44 55) arithmeticMean closeTo: 29.4). |
3863 TestCase assert:( { 13. 23. 12. 44. 55 } standardDeviation closeTo: 19.2431). |
3895 TestCase assert:( #(13 23 12 44 55) standardDeviation closeTo: 19.2431). |
3864 " |
3896 " |
3865 |
3897 |
3866 "Created: / 13-04-2011 / 17:58:47 / cg" |
3898 "Created: / 13-04-2011 / 17:58:47 / cg" |
3867 ! ! |
3899 ! ! |
3868 |
3900 |
4363 ! ! |
4395 ! ! |
4364 |
4396 |
4365 !Collection class methodsFor:'documentation'! |
4397 !Collection class methodsFor:'documentation'! |
4366 |
4398 |
4367 version |
4399 version |
4368 ^ '$Header: /cvs/stx/stx/libbasic/Collection.st,v 1.276 2012/07/20 13:05:23 cg Exp $' |
4400 ^ '$Header: /cvs/stx/stx/libbasic/Collection.st,v 1.281 2012/08/21 12:49:44 cg Exp $' |
4369 ! |
4401 ! |
4370 |
4402 |
4371 version_CVS |
4403 version_CVS |
4372 ^ '§Header: /cvs/stx/stx/libbasic/Collection.st,v 1.276 2012/07/20 13:05:23 cg Exp §' |
4404 ^ '§Header: /cvs/stx/stx/libbasic/Collection.st,v 1.281 2012/08/21 12:49:44 cg Exp §' |
4373 ! |
4405 ! |
4374 |
4406 |
4375 version_SVN |
4407 version_SVN |
4376 ^ '$Id: Collection.st 10829 2012-07-25 08:45:15Z vranyj1 $' |
4408 ^ '$Id: Collection.st 10844 2012-09-07 16:24:32Z vranyj1 $' |
4377 ! ! |
4409 ! ! |
4378 |
4410 |
4379 Collection initialize! |
4411 Collection initialize! |