Enhancing SequenceableCollection>>combinationsAt:in:after:do:
In Pharo 1.3, SequenceableCollection>>combinations:atATimeDo: will, for all combinations, send the same collection instance as argument for the block. Therefore, if you use this collection itself, you will be surprised: |answer| answer := OrderedCollection new. #(a b c) combinations: 2 atATimeDo: [:each | answer add: each]. answer Here I expect to end up with a collection looking like this: 1: #(#a #b) 2: #(#a #c) 3: #(#b #c) But I end up with: 1: #(#c #c) 2: #(#c #c) 3: #(#c #c) One fix is to change the client code to copy the argument for the block: |answer| answer := OrderedCollection new. #(a b c) combinations: 2 atATimeDo: [:each | answer add: each copy]. answer Another solution is enhancing SequenceableCollection>>combinationsAt:in:after:do: to copy the collection: nn + 1 to: self size do: [ :index | aCollection at: jj put: (self at: index). jj = aCollection size ifTrue: [ aBlock value: aCollection copy ] ifFalse: [ self combinationsAt: jj + 1 in: aCollection after: index do: aBlock ] ] Kind regards Runar Jordahl blog.epigent.com
Thanks can you propose some tests? Did you sign the license agreement? Stef On Nov 2, 2011, at 7:57 PM, Runar Jordahl wrote:
In Pharo 1.3, SequenceableCollection>>combinations:atATimeDo: will, for all combinations, send the same collection instance as argument for the block. Therefore, if you use this collection itself, you will be surprised:
|answer| answer := OrderedCollection new. #(a b c) combinations: 2 atATimeDo: [:each | answer add: each]. answer
Here I expect to end up with a collection looking like this: 1: #(#a #b) 2: #(#a #c) 3: #(#b #c)
But I end up with: 1: #(#c #c) 2: #(#c #c) 3: #(#c #c)
One fix is to change the client code to copy the argument for the block: |answer| answer := OrderedCollection new. #(a b c) combinations: 2 atATimeDo: [:each | answer add: each copy]. answer
Another solution is enhancing SequenceableCollection>>combinationsAt:in:after:do: to copy the collection: nn + 1 to: self size do: [ :index | aCollection at: jj put: (self at: index). jj = aCollection size ifTrue: [ aBlock value: aCollection copy ] ifFalse: [ self combinationsAt: jj + 1 in: aCollection after: index do: aBlock ] ]
Kind regards Runar Jordahl blog.epigent.com
participants (2)
-
Runar Jordahl -
Stéphane Ducasse