Lukas

I know that you also have a cool lib of other highorder function.
Where can we find it?

Stef

On Dec 27, 2009, at 5:26 PM, Stéphane Ducasse wrote:

> hi 
> 
> here are the collection extensions we use in Moose.
> I copied them to PharoTaskForces so that we can discuss and tweak the code if 
> wanted.
> 
> My favorite is 
>       flatCollect:/flatCollectAsSet: 
>       groupedBy:
>       
>       There are really useful. 
> 
> Stef
> 
> 
> testFlatCollectArray
>       "self debug: #testFlatCollectArray"
>       
>       self assert: ((#((1 2) (3 4) (5 3)) flatCollect: [ :each ]) = #(1 2 3 4 
> 5 3)).
>       self assert: ((#((1 2) (2 3) (1 3 4)) flatCollect: [:each]) = #(1 2 2 3 
> 1 3 4)).        
>               
>       self assert: ((#((1 2) (2 3) () ()) flatCollect: [:each]) = #(1 2 2 
> 3)). 
> 
>       self assert: ((#((1 2) (2 3) (1 3 4)) flatCollect: [:each| Array with: 
> each])
>                                       =  #(#(1 2) #(2 3) #(1 3 4))).
>                                       
>       self assert: ((#((1 2) (2 3) (1 3 4)) flatCollect: [:each| Set with: 
> each])
>                                       =  #(#(1 2) #(2 3) #(1 3 4))).  
>       
> 
> testFlatCollectSet
>       "self debug: #testFlatCollectSet"
>       
>       self assert: ((#((1 2) (1 2) (1 3 4)) asSet  flatCollect: [:each]) = 
> #(1 1 2 3 4) asSet).
>       self assert: ((#() asSet flatCollect: [:each]) = #() asSet).
> 
>       self assert:  ((#((1 2) () (1 3 4)) asSet  flatCollect: [:each]) = #(1 
> 1 2 3 4) asSet).
>       self assert:  ((#((1 2) #((99)) (1 3 4)) asSet  flatCollect: [:each]) 
>                                       = #(1 1 2 3 4 (99)) asSet).
>       self assert:  ((#((1 2) #(()) (1 3 4)) asSet  flatCollect: [:each]) 
>                                       = #(1 1 2 3 4 ()) asSet).
> 
> testCollectAsSet
>       "self debug: #testCollectAsSet"
>       
>       self assert: ((#() collectAsSet: [:each | each odd]) = Set new).
>       self assert: (#(1 2 3 4 5 6) collectAsSet: [:each | each odd])
>                                        = (Set with: true with: false).
>       self assert: (#(1 3 5 7 9 11) collectAsSet: [:each | each odd]) 
>                                       = (Set with: true).
>                                       
>       self assert: (#(1 2 3 4 5 4 3 2 1) collectAsSet: [:each | each]) = (1 
> to: 5) asSet.
>       
>       
> testGroupedByArray
>       "self debug: #testGroupedByArray"
>       
>       | res |
>       res := #(1 2 3 4 5) groupedBy: [:each | each odd].
>       self assert:   (res at: true) = #(1 3 5).
>       self assert: (res at: false) = #(2 4)
> 
> 
> 
> Set>>flatCollect: aBlock 
>       
>       
>       ^self flatCollectAsSet: aBlock
> 
> 
> Symbol>>value
>       "Allow this object to act as a ValueHolder on itself."
> 
>       ^self
> 
> OrderedCollection>>removeAtIndex: anIndex
>       "Remove the element of the collection at position anIndex.  Answer the 
> object removed."
> 
>       | obj |
>       obj := self at: anIndex.
>       self removeIndex: anIndex + firstIndex - 1.
>       ^obj
> 
> Collection 
> ==============================
> 
> collectAsSet: aBlock
>       "Evaluates aBlock for each element of the receiver and collects
>       the resulting values into a Set."
> 
>       "This is an efficient shorthand for [ (self collect: aBlock) asSet ]."
>       "originally developed by a. kuhn and released under MIT."
>       
>       ^self inject: Set new into: [ :set :each | 
>               set add: (aBlock value: each); yourself ].
> 
> 
> copyEmpty: aSize
>       "Answer a copy of the receiver that contains no elements.
> 
>       This method should be redefined in subclasses that add
>       instance variables, so that the state of those variables
>       is preserved"
> 
>       ^self class new: aSize
> 
> 
> flatCollect: aBlock 
>       "Evaluate aBlock for each of the receiver's elements and answer the
>       list of all resulting values flatten one level. Assumes that aBlock 
> returns some kind
>       of collection for each element. Equivalent to the lisp's mapcan"
>       "original written by a. Kuhn and released under MIT"
>       
>       | stream |
>       self isEmpty ifTrue: [ ^ self copy ].
>       stream := (self species new: 0) nsWriteStream.
>       self do: [ :each | stream nextPutAll: (aBlock value: each) ].
>       ^ stream contents
> 
> flatCollectAsSet: aBlock
>       "Evaluate aBlock for each of the receiver's elements and answer the
>       list of all resulting values flatten one level. Assumes that aBlock 
> returns some kind
>       of collection for each element. Equivalent to the lisp's mapcan"
>       
>       "original written by a. Kuhn and released under MIT"
>       
>       | set |
>       self isEmpty ifTrue: [^self copy ].
>       set := Set new.         
>       self do: [ :each |
>               set addAll: (aBlock value: each) ].
>       ^set
> 
> 
> flatten
>       "Recursively collect each non-collection element of the receiver and 
> its descendant
>       collections.  Please note, this implementation assumes that strings are 
> to be treated
>       as objects rather than as collection."
> 
>       ^self gather: [ :each ]
> 
> groupedBy: aBlock
>       "Return a dictionary whose keys are the result of evaluating aBlock for 
> all elements in
>        the collection, and the value for each key is the collection of 
> elements that evaluated
>        to that key. e.g.
>            #(1 2 3 4 5) groupedBy: [:each | each odd]
>          a Dictionary  
>            true ---> #( 1 3 5)
>            false --> #(2 4)
>       originally developed by a. kuhn and released under MIT."
> 
>       | result |
>       result := Dictionary new.
>       self do:
>               [:each | | key collection |
>               key := aBlock value: each.
>               collection := result at: key ifAbsentPut: [OrderedCollection 
> new].
>               collection add: each].
>       self species ~~ OrderedCollection ifTrue:
>               ["Convert the result collections to be the right type.
>                 Note that it should be safe to modify the dictionary
>                 while iterating because we only replace values for existing 
> keys"
>               result keysAndValuesDo:
>                       [:key :value | result at: key put: (self species 
> withAll: value)]].
> 
>       ^result
> 
> includesAll: aCollection 
>       "Answer true if the receiver includes all elements of aCollection with 
> at
>       least as many occurrences as in aCollection. For a less strict 
> comparison
>       please refer to supersetOf: and its inverse subsetOf:."
> 
> 
>       ^(aCollection isCollection) and: [
>               aCollection size <= self size and: [
>                       aCollection allSatisfy: [ :each | 
>                               (aCollection occurrencesOf: each) <= (self 
> occurrencesOf: each) ]]]
> 
> nilSafeGroupedBy: aBlock
>       ^ self groupedBy: [ :each |
>               | value |
>               value := aBlock value: each.
>               value ifNil: [ UndefinedObject ].
>       ]       
> 
> selectAsSet: aBlock 
>       "Evaluate aBlock with each of the receiver's elements as the argument. 
>       Collect into a new set, only those elements for which
>       aBlock evaluates to true.  Answer the new collection."
> 
>       | newSet |
>       newSet := Set new.
>       self do: [:each | (aBlock value: each) ifTrue: [newSet add: each]].
>       ^newSet
> 
> shuffle
>       "Swaps the receiver's elements at random."
> 
>       self shuffle: (self size * self size log) asInteger
> 
> sum: aSymbolOrBlock 
>        
>       ^self 
>               inject: 0 
>               into: [:sum :each | sum + (aSymbolOrBlock value: each)]
> 
> shuffle: times
>       "Swaps random elements of the receiver."
> 
>       | size random |
>       size := self size.
>       random := Random new.
>       times timesRepeat: [ 
>               self swap: (random next * size) floor + 1 with: (random next * 
> size) floor + 1 
>       ].
> 
> 
> 
> 
> _______________________________________________
> Pharo-project mailing list
> [email protected]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to