Collection.st
changeset 19459 3bcd4f73da62
parent 19306 437d8365fb5d
child 19478 1f5aa87f6170
child 19586 8b7a610ea316
--- a/Collection.st	Fri Mar 25 17:06:15 2016 +0100
+++ b/Collection.st	Fri Mar 25 17:07:10 2016 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
               All Rights Reserved
@@ -277,6 +275,7 @@
     ^ self newWithSize:n
 ! !
 
+
 !Collection class methodsFor:'Signal constants'!
 
 emptyCollectionSignal
@@ -333,7 +332,7 @@
 isAbstract
     "Return if this class is an abstract class.
      True is returned for Collection here; false for subclasses.
-     Abstract subclasses must redefine again."
+     Abstract subclasses must redefine this again."
 
     ^ self == Collection
 ! !
@@ -491,6 +490,8 @@
 !
 
 ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
+    "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
+    
     |action|
 
     action := self isEmpty ifTrue:[ ifEmptyValue ] ifFalse:[ ifNotEmptyValue ].
@@ -504,31 +505,44 @@
 !
 
 ifEmpty:ifEmptyValue ifNotEmptyDo:ifNotEmptyValue
+    "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
+
     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
 !
 
 ifEmptyDo:ifEmptyValue ifNotEmpty:ifNotEmptyValue
+    "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
+
     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
 !
 
 ifNotEmpty:ifNotEmptyValue
+    "return ifNotEmptyValue if not empty, nil otherwise"
+
     ^ self ifEmpty:nil ifNotEmpty:ifNotEmptyValue
 !
 
 ifNotEmptyDo:ifNotEmptyValue
+    "return ifNotEmptyValue if not empty, nil otherwise"
+
     ^ self ifEmpty:nil ifNotEmpty:ifNotEmptyValue
 !
 
 ifNotEmptyDo:ifNotEmptyValue ifEmpty:ifEmptyValue
+    "return ifNotEmptyValue if not empty, ifEmptyValue otherwise"
+
     ^ self ifEmpty:ifEmptyValue ifNotEmpty:ifNotEmptyValue
 !
 
 intersection:aCollection
+    "same as intersect: for Squeak compatibility"
+    
     ^ self intersect:aCollection
 
     "Created: / 22-10-2008 / 21:29:27 / cg"
 ! !
 
+
 !Collection methodsFor:'accessing'!
 
 anElement
@@ -1113,7 +1127,7 @@
      Notice: for some collections (those not tuned for
              resizing themself) this may be very slow.
              If the number of removed elements is big compared to to
-             the receivers size, it may be better to copy the
+             the receiver's size, it may be better to copy the
              ones which are not to be removed into a new collection."
 
     aCollection do:[:element | self remove:element].
@@ -1182,7 +1196,7 @@
      Notice: for some collections (those not tuned for
              resizing themself) this may be very slow.
              If the number of removed elements is big compared to to
-             the receivers size, it may be better to copy the
+             the receiver's size, it may be better to copy the
              ones which are not to be removed into a new collection."
 
     aCollection do:[:element | self removeIdentical:element].
@@ -2617,7 +2631,7 @@
 
 detect:checkBlock thenCompute:evalBlock 
     "evaluate the argument, aBlock for each element in the receiver until
-     chloeckBck returns true; in this case return the value from evalBlock
+     checkBck returns true; in this case return the value from evalBlock
      applied to the element which caused the true evaluation.
      If none of the evaluations returns true, report an error"
 
@@ -2631,7 +2645,7 @@
 
 detect:checkBlock thenCompute:evalBlock ifNone:exceptionValue
     "evaluate the argument, aBlock for each element in the receiver until
-     chloeckBck returns true; in this case return the value from evalBlock
+     checkBck returns true; in this case return the value from evalBlock
      applied to the element which caused the true evaluation.
      If none of the evaluations returns true, return the value from exceptionValue."
 
@@ -2682,9 +2696,9 @@
 
 detectMax: aBlock
     "Evaluate aBlock with each of the receiver's elements as the argument. 
-    Answer the element for which aBlock evaluates to the highest magnitude.
-    If the receiver collection is empty, return nil.  
-    This method might also be called elect:."
+     Answer the element for which aBlock evaluates to the highest magnitude.
+     If the receiver collection is empty, return nil.  
+     This method might also be called elect:."
 
     | maxElement maxValue |
 
@@ -2692,9 +2706,9 @@
         | val |
 
         val := aBlock value: each.
-        "Note that there is no way to get the first element that works 
-        for all kinds of Collections.  
-        Must test every one (maxValue is nil for the first element)."
+        "Note that there is no way to get the first element 
+         which works for all kinds of Collections.  
+         Must therefore test every one (maxValue is nil for the first element)."
         (maxValue == nil or:[val > maxValue]) ifTrue: [
            maxElement := each.
            maxValue := val
@@ -2711,8 +2725,8 @@
 
 detectMin: aBlock
     "Evaluate aBlock with each of the receiver's elements as the argument. 
-    Answer the element for which aBlock evaluates to the lowest number.
-    If the receiver collection is empty, return nil."
+     Answer the element for which aBlock evaluates to the lowest number.
+     If the receiver collection is empty, return nil."
 
     | minElement minValue |
 
@@ -2720,9 +2734,9 @@
         | val |
 
         val := aBlock value: each.
-        "Note that there is no way to get the first element that works 
-        for all kinds of Collections.  
-        Must test every one (maxValue is nil for the first element)."
+        "Note that there is no way to get the first element 
+         which works for all kinds of Collections.  
+         Must therefore test every one (minValue is nil for the first element)."
         (minValue == nil or:[val < minValue]) ifTrue: [
            minElement := each.
            minValue := val
@@ -2856,7 +2870,6 @@
      Answer true, if all the elements have been processed,
      false otherwise."
 
-
     self do:[:el |
         (aBlock value:el) ifFalse:[
             ^ false.
@@ -3178,14 +3191,16 @@
 
 keysAndValuesDo:aTwoArgBlock
     "evaluate the argument, aBlock for every element in the collection,
-     passing both index and element as arguments."
+     passing both index and element as arguments.
+     Blocked here - must be redefined in subclasses which have keyed elements"
 
     ^ self errorNotKeyed
 !
 
 keysAndValuesReverseDo:aTwoArgBlock
     "evaluate the argument, aBlock in reverse order for every element in the collection,
-     passing both index and element as arguments."
+     passing both index and element as arguments.
+     Blocked here - must be redefined in subclasses which have keyed elements"
 
     ^ self errorNotKeyed
 
@@ -3193,6 +3208,10 @@
 !
 
 keysAndValuesSelect:selectBlockWith2Args thenCollect:collectBlockWith2Args
+    "first call the selectBlockWith2Args, passsing it each key and element,
+     if that returns true, call the collectBlockWith2Args, also with key and element,
+     and collect the resulting values in an OrderedCollection."
+    
     |collected|
 
     collected := OrderedCollection new.
@@ -3204,7 +3223,9 @@
     ^ collected
 
     "
-     #(10 20 30 40) keysAndValuesSelect:[:idx :val | idx > 2] thenCollect:[:idx :val | idx->val]
+     #(10 20 30 40) 
+        keysAndValuesSelect:[:idx :val | idx > 2] 
+        thenCollect:[:idx :val | idx->val]
     "
 !
 
@@ -3534,7 +3555,7 @@
 !
 
 select:selectBlock thenDo:doBlock
-    "combination of select followed by do
+    "combination of select followed by do.
      The same as if two separate select:+do: messages were sent,
      but avoids the creation of intermediate collections, 
      so this is nicer for big collections."
@@ -3550,6 +3571,25 @@
     "
 !
 
+selectWithIndex:aTwoArgBlock
+    "return a new collection with all elements from the receiver, 
+     for which the argument aBlock evaluates to true.
+     aTwoArgBlock is called with value and index as arguments."
+
+    |newCollection|
+
+    newCollection := self species new.
+    self doWithIndex:[:eachValue :eachKey |
+        (aTwoArgBlock value:eachValue value:eachKey) ifTrue:[newCollection add:eachValue].
+    ].
+    ^ newCollection
+
+    "
+     #(10 20 30 40) selectWithIndex:[:e :i | i odd]   
+     #(10 20 30 40) selectWithIndex:[:e :i | i even]   
+    "
+!
+
 triplesDo:aThreeArgBlock
     "evaluate the argument, aThreeArgBlock for every element in the collection,
      which is supposed to consist of 3-element collections.
@@ -4199,7 +4239,7 @@
     aStream nextPut:$)
 
     "
-     #(1 2 3 'hello' $a $ü) printOn:Transcript
+     #(1 2 3 'hello' $a $ü) printOn:Transcript
      (Array new:100000) printOn:Transcript
      (Array new:100000) printOn:Stdout          
      (Array new:100000) printString size 
@@ -4302,10 +4342,18 @@
 !
 
 isReadOnly
+    "true if this is a readOnly (immutable) collection.
+     Q1: should this be called isImmutable?
+     Q2: who uses this?"
+    
     ^ false
 !
 
 isWritable
+    "true if this is not a readOnly (immutable) collection.
+     Q1: should this be called isMutable?
+     Q2: who uses this?"
+
     ^ self isReadOnly not
 !
 
@@ -5529,7 +5577,7 @@
 includesAll:aCollection
     "return true, if the the receiver includes all elements of
      the argument, aCollection; false if any is missing.
-     Notice: this method has O-square runtime behavior and may be
+     Notice: this method has O² runtime behavior and may be
              slow for big receivers/args. 
              Think about using a Set, or Dictionary."
 
@@ -5548,7 +5596,7 @@
     "return true, if the the receiver includes any elements of
      the argument, aCollection; false if it includes none.
      Notice: 
-        this method has O^2(N) runtime behavior and may be
+        this method has O² runtime behavior and may be
         slow for big receivers/args. 
         Think about using a Set or Dictionary. 
         Some speedup is also possible, by arranging highly
@@ -5612,7 +5660,7 @@
     "return true, if the the receiver includes any elements of
      the argument, aCollection; false if it includes none.
      Use identity compare for comparing.
-     Notice: this method has O^2(N) runtime behavior and may be
+     Notice: this method has O² runtime behavior and may be
              slow for big receivers/args. 
              Think about using a Set or Dictionary. 
              Some speedup is also possible, by arranging highly