Hi guys. This is a thing that I encounter quite often. Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like: projects sortByProp: #creationDate or by birth date of the author projects sortByProp: [ :proj | proj author birthDate ] Maybe Iâm wrong, but as Iâve told already I encounter it quite often and writing something like projects sortBy: [ :prev :next | prev creationDate <= next creationDate ] is boring for me. Cheers. Uko
Hi Yuriy, I though the same. There is a similar situation with pluggable collections where you have to specify two blocks: one for the hash the other for equality. So you have to repeat three times the property you're interested in: PluggableSet new hashBlock: [ :each | each name hash ]; equalBlock: [ :a :b | a name = b name ]; yourself. Where I would like to be able to write: PluggableSet by: #name. On 11 mars 2014, at 09:19, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe Iâm wrong, but as Iâve told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
Hello, [ Note: So in the default Pharo the method is named #sort: not #sortByProp: or #sortBy: but it's a detail ] I like this idea because I also have always the problem. So I would like to be able to do: projects sort: #creationDate The implementation would be, in a similar fashion to how Symbol>>value: is implemented for aCollection collect: #isPlague : Symbol>>value: val1 value: val2 ^ (val1 perform: self) <= (val2 perform: self) Then : (#( 10 42 31 23 90 87 65) collect: #asValueHolder) sort: #value Answers: an Array(a NewValueHolder[ 10 ] a NewValueHolder[ 23 ] a NewValueHolder[ 31 ] a NewValueHolder[ 42 ] a NewValueHolder[ 65 ] a NewValueHolder[ 87 ] a NewValueHolder[ 90 ]) which is correct :-). However I do not like: projects sort: [ :proj | proj author birthDate ] If you allow that where is the limit to the thing you want to allow ? In addition, I do not see any nice implementation and you could just implement in project Project>>authorBirthDate ^ self author birthDate Best, Clement 2014-03-11 9:19 GMT+01:00 Yuriy Tymchuk <yuriy.tymchuk@me.com>:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe I'm wrong, but as I've told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
On 11 Mar 2014, at 10:19, Clément Bera <bera.clement@gmail.com> wrote:
Hello,
[ Note: So in the default Pharo the method is named #sort: not #sortByProp: or #sortBy: but it's a detail ]
Yes, my mistake, I was misguided by #isSortedBy: Now #sortByProp: is my own example method that accepts a block and executes it for each sortable item and then the result is compared. I donât like the idea to implement #value:value: for a symbol because it caries a bit of a logic inside it. Uko
I like this idea because I also have always the problem. So I would like to be able to do:
projects sort: #creationDate
The implementation would be, in a similar fashion to how Symbol>>value: is implemented for aCollection collect: #isPlague :
Symbol>>value: val1 value: val2 ^ (val1 perform: self) <= (val2 perform: self)
Then :
(#( 10 42 31 23 90 87 65) collect: #asValueHolder) sort: #value
Answers:
an Array(a NewValueHolder[ 10 ] a NewValueHolder[ 23 ] a NewValueHolder[ 31 ] a NewValueHolder[ 42 ] a NewValueHolder[ 65 ] a NewValueHolder[ 87 ] a NewValueHolder[ 90 ])
which is correct :-).
However I do not like:
projects sort: [ :proj | proj author birthDate ]
If you allow that where is the limit to the thing you want to allow ? In addition, I do not see any nice implementation and you could just implement in project
Project>>authorBirthDate ^ self author birthDate
Best,
Clement
2014-03-11 9:19 GMT+01:00 Yuriy Tymchuk <yuriy.tymchuk@me.com>: Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe Iâm wrong, but as Iâve told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
Hello, @Uko Well I implemented Symbol>>value:value: in a similar fashion than Symbol>>value: for 'aCollection collect: #aSymbol'. But that's not a perfect solution for sure. @Camille I used PluggableSet and PluggableDictionary in my project and they were so slow that in the end I implemented my own collection. It will be a real alternative when we will have clean blocks. (For that we need to merge with Cog's trunk which includes merging Spur)... 2014-03-11 10:45 GMT+01:00 Yuriy Tymchuk <yuriy.tymchuk@me.com>:
On 11 Mar 2014, at 10:19, Clément Bera <bera.clement@gmail.com> wrote:
Hello,
[ Note: So in the default Pharo the method is named #sort: not #sortByProp: or #sortBy: but it's a detail ]
Yes, my mistake, I was misguided by #isSortedBy:
Now #sortByProp: is my own example method that accepts a block and executes it for each sortable item and then the result is compared.
I don't like the idea to implement #value:value: for a symbol because it caries a bit of a logic inside it.
Uko
I like this idea because I also have always the problem. So I would like to be able to do:
projects sort: #creationDate
The implementation would be, in a similar fashion to how Symbol>>value: is implemented for aCollection collect: #isPlague :
Symbol>>value: val1 value: val2 ^ (val1 perform: self) <= (val2 perform: self)
Then :
(#( 10 42 31 23 90 87 65) collect: #asValueHolder) sort: #value
Answers:
an Array(a NewValueHolder[ 10 ] a NewValueHolder[ 23 ] a NewValueHolder[ 31 ] a NewValueHolder[ 42 ] a NewValueHolder[ 65 ] a NewValueHolder[ 87 ] a NewValueHolder[ 90 ])
which is correct :-).
However I do not like:
projects sort: [ :proj | proj author birthDate ]
If you allow that where is the limit to the thing you want to allow ? In addition, I do not see any nice implementation and you could just implement in project
Project>>authorBirthDate ^ self author birthDate
Best,
Clement
2014-03-11 9:19 GMT+01:00 Yuriy Tymchuk <yuriy.tymchuk@me.com>:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe I'm wrong, but as I've told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
hi Uko, For Roassal, we have a #sortedAs: defined on all collections -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect" | aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4) Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag â¦) This is really handy. It should be part of Pharo I believe. Cheers, Alexandre On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe Iâm wrong, but as Iâve told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
Hi Alexandre, IMO the isKindOf:, apart from being ugly, will hurt performance badly. Why not apply aSortBlockOrSymbol to the first element and then choose the block appropriately? e.g. aSortBlockOrSymbol isSymbol ifTrue: [(#(true false) includes: (self first perform: aSortBlockOrSymbol) ifTrue: [[:a :b | (a perform: aSortBlockOrSymbol)]] ifFalse: [[:a :b | (a perform: aSortBlockOrSymbol) < (b perform: aSortBlockOrSymbol)]]] ... Nicer to read and faster, no? On Tue, Mar 11, 2014 at 8:17 AM, Alexandre Bergel <alexandre.bergel@me.com>wrote:
hi Uko,
For Roassal, we have a #sortedAs: defined on all collections
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect"
| aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4)
Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag ...)
This is really handy. It should be part of Pharo I believe.
Cheers, Alexandre
On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe I'm wrong, but as I've told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
-- best, Eliot
On Tue, Mar 11, 2014 at 12:19 PM, Eliot Miranda <eliot.miranda@gmail.com>wrote:
Hi Alexandre,
IMO the isKindOf:, apart from being ugly, will hurt performance badly. Why not apply aSortBlockOrSymbol to the first element and then choose the block appropriately? e.g.
aSortBlockOrSymbol isSymbol ifTrue: [(#(true false) includes: (self first perform: aSortBlockOrSymbol) ifTrue: [[:a :b | (a perform: aSortBlockOrSymbol)]] ifFalse: [[:a :b | (a perform: aSortBlockOrSymbol) < (b perform: aSortBlockOrSymbol)]]] ...
Nicer to read and faster, no?
On Tue, Mar 11, 2014 at 8:17 AM, Alexandre Bergel <alexandre.bergel@me.com
wrote:
hi Uko,
For Roassal, we have a #sortedAs: defined on all collections
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect"
| aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4)
Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag ...)
This is really handy. It should be part of Pharo I believe.
Cheers, Alexandre
On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe I'm wrong, but as I've told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
-- best, Eliot
-- best, Eliot
and here's one with a better comment that includes examples On Tue, Mar 11, 2014 at 12:19 PM, Eliot Miranda <eliot.miranda@gmail.com>wrote:
Hi Alexandre,
IMO the isKindOf:, apart from being ugly, will hurt performance badly. Why not apply aSortBlockOrSymbol to the first element and then choose the block appropriately? e.g.
aSortBlockOrSymbol isSymbol ifTrue: [(#(true false) includes: (self first perform: aSortBlockOrSymbol) ifTrue: [[:a :b | (a perform: aSortBlockOrSymbol)]] ifFalse: [[:a :b | (a perform: aSortBlockOrSymbol) < (b perform: aSortBlockOrSymbol)]]] ...
Nicer to read and faster, no?
On Tue, Mar 11, 2014 at 8:17 AM, Alexandre Bergel <alexandre.bergel@me.com
wrote:
hi Uko,
For Roassal, we have a #sortedAs: defined on all collections
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect"
| aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4)
Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag ...)
This is really handy. It should be part of Pharo I believe.
Cheers, Alexandre
On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe I'm wrong, but as I've told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
-- best, Eliot
-- best, Eliot
Thanks eliot. On 11 Mar 2014, at 20:51, Eliot Miranda <eliot.miranda@gmail.com> wrote:
and here's one with a better comment that includes examples
On Tue, Mar 11, 2014 at 12:19 PM, Eliot Miranda <eliot.miranda@gmail.com> wrote: Hi Alexandre,
IMO the isKindOf:, apart from being ugly, will hurt performance badly. Why not apply aSortBlockOrSymbol to the first element and then choose the block appropriately? e.g.
aSortBlockOrSymbol isSymbol ifTrue: [(#(true false) includes: (self first perform: aSortBlockOrSymbol) ifTrue: [[:a :b | (a perform: aSortBlockOrSymbol)]] ifFalse: [[:a :b | (a perform: aSortBlockOrSymbol) < (b perform: aSortBlockOrSymbol)]]] ...
Nicer to read and faster, no?
On Tue, Mar 11, 2014 at 8:17 AM, Alexandre Bergel <alexandre.bergel@me.com> wrote: hi Uko,
For Roassal, we have a #sortedAs: defined on all collections
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect"
| aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4)
Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag â¦)
This is really handy. It should be part of Pharo I believe.
Cheers, Alexandre
On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe Iâm wrong, but as Iâve told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
-- best, Eliot
-- best, Eliot <SequenceableCollection-sortedAs.st>
Hi Since Symbol and Blocks are polymorphic could we not simplify the code to be: SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlockOrSymbol. The receiver cannot be empty. Answer a new collection. This method does not side effect the receiver. e.g. SequenceableCollection withAllSubclasses sortedAs: #name. SequenceableCollection withAllSubclasses sortedAs: [:class | class methodDict size]." | aSortBlock | aSortBlock := (#(true false ) includes: (aSortBlockOrSymbol value: self first)) ifTrue: [[:a :b | aSortBlockOrSymbol value: a]] ifFalse: [[:a :b | (aSortBlockOrSymbol value: a) < (aSortBlockOrSymbol value: b)]]. ^ (SortedCollection new: self size) sortBlock: aSortBlock; addAll: self; yourself Cheers Carlo On 12 Mar 2014, at 12:32 AM, Pharo4Stef <pharo4Stef@free.fr> wrote: Thanks eliot. On 11 Mar 2014, at 20:51, Eliot Miranda <eliot.miranda@gmail.com> wrote:
and here's one with a better comment that includes examples
On Tue, Mar 11, 2014 at 12:19 PM, Eliot Miranda <eliot.miranda@gmail.com> wrote: Hi Alexandre,
IMO the isKindOf:, apart from being ugly, will hurt performance badly. Why not apply aSortBlockOrSymbol to the first element and then choose the block appropriately? e.g.
aSortBlockOrSymbol isSymbol ifTrue: [(#(true false) includes: (self first perform: aSortBlockOrSymbol) ifTrue: [[:a :b | (a perform: aSortBlockOrSymbol)]] ifFalse: [[:a :b | (a perform: aSortBlockOrSymbol) < (b perform: aSortBlockOrSymbol)]]] ...
Nicer to read and faster, no?
On Tue, Mar 11, 2014 at 8:17 AM, Alexandre Bergel <alexandre.bergel@me.com> wrote: hi Uko,
For Roassal, we have a #sortedAs: defined on all collections
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect"
| aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4)
Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag â¦)
This is really handy. It should be part of Pharo I believe.
Cheers, Alexandre
On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe Iâm wrong, but as Iâve told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
-- best, Eliot
-- best, Eliot <SequenceableCollection-sortedAs.st>
Hi Otto I think the main reason is to support the second usage scenario: SequenceableCollection withAllSubclasses sortedAs: [:class | class methodDict size]. We could try and unify the sort: method to take only blocks while sortedAs: a symbol but then at the same time we could just put everything into one method and use cull: perhaps to handle all the scenarios. Personally I donât feel too comfortable with the code below, apart from the performance penalties it also feels like code that is too âcleverâ for itself which obviously makes it complicated to understand and modify. I wrote it mainly for people to voice opinions and get ideas flowing. Iâd have 2 separate sort methods so that users can choose if they want the runtime characteristics of either. Example which can handle all current scenarios i.e. symbol or block taking 1 or 2 arguments: SequenceableCollection>>sort: aSortBlock self mergeSortFrom: 1 to: self size by: (self createSortBlock: aSortBlock) SequenceableCollection>>createSortBlock: aSortBlockOrSymbol ^ aSortBlockOrSymbol numArgs < 2 ifTrue: [[ :a :b | (#(true false ) includes: (aSortBlockOrSymbol value: a)) ifTrue: [ aSortBlockOrSymbol value: a] ifFalse: [(aSortBlockOrSymbol value: a) < (aSortBlockOrSymbol value: b)]]] ifFalse: [[:a :b | aSortBlockOrSymbol cull: a cull: b]] BTW the previous versions had a bug where it fails when called on an empty collection as the true/false check is done eagerly. Cheers Carlo -- View this message in context: http://forum.world.st/Sort-by-property-tp4748500p4748757.html Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
I presume you all know about Griggs work on the subject http://stackoverflow.com/questions/8204826/smalltalk-sort-a-collection-by-tw... http://objology.blogspot.com/2010/11/tag-sortfunctions.html 2014-03-12 11:23 GMT+01:00 carlo.t <snoobabk@yahoo.ie>:
Hi Otto
I think the main reason is to support the second usage scenario: SequenceableCollection withAllSubclasses sortedAs: [:class | class methodDict size]. We could try and unify the sort: method to take only blocks while sortedAs: a symbol but then at the same time we could just put everything into one method and use cull: perhaps to handle all the scenarios.
Personally I don't feel too comfortable with the code below, apart from the performance penalties it also feels like code that is too 'clever' for itself which obviously makes it complicated to understand and modify. I wrote it mainly for people to voice opinions and get ideas flowing. I'd have 2 separate sort methods so that users can choose if they want the runtime characteristics of either.
Example which can handle all current scenarios i.e. symbol or block taking 1 or 2 arguments: SequenceableCollection>>sort: aSortBlock self mergeSortFrom: 1 to: self size by: (self createSortBlock: aSortBlock)
SequenceableCollection>>createSortBlock: aSortBlockOrSymbol ^ aSortBlockOrSymbol numArgs < 2 ifTrue: [[ :a :b | (#(true false ) includes: (aSortBlockOrSymbol value: a)) ifTrue: [ aSortBlockOrSymbol value: a] ifFalse: [(aSortBlockOrSymbol value: a) < (aSortBlockOrSymbol value: b)]]] ifFalse: [[:a :b | aSortBlockOrSymbol cull: a cull: b]]
BTW the previous versions had a bug where it fails when called on an empty collection as the true/false check is done eagerly.
Cheers Carlo
-- View this message in context: http://forum.world.st/Sort-by-property-tp4748500p4748757.html Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
Is this multisort feature available for Pharo somewhere? Regards! Esteban A. Maringolo 2014-03-12 7:45 GMT-03:00 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>:
I presume you all know about Griggs work on the subject
http://stackoverflow.com/questions/8204826/smalltalk-sort-a-collection-by-tw... http://objology.blogspot.com/2010/11/tag-sortfunctions.html
2014-03-12 11:23 GMT+01:00 carlo.t <snoobabk@yahoo.ie>:
Hi Otto
I think the main reason is to support the second usage scenario: SequenceableCollection withAllSubclasses sortedAs: [:class | class methodDict size]. We could try and unify the sort: method to take only blocks while sortedAs: a symbol but then at the same time we could just put everything into one method and use cull: perhaps to handle all the scenarios.
Personally I don't feel too comfortable with the code below, apart from the performance penalties it also feels like code that is too 'clever' for itself which obviously makes it complicated to understand and modify. I wrote it mainly for people to voice opinions and get ideas flowing. I'd have 2 separate sort methods so that users can choose if they want the runtime characteristics of either.
Example which can handle all current scenarios i.e. symbol or block taking 1 or 2 arguments: SequenceableCollection>>sort: aSortBlock self mergeSortFrom: 1 to: self size by: (self createSortBlock: aSortBlock)
SequenceableCollection>>createSortBlock: aSortBlockOrSymbol ^ aSortBlockOrSymbol numArgs < 2 ifTrue: [[ :a :b | (#(true false ) includes: (aSortBlockOrSymbol value: a)) ifTrue: [ aSortBlockOrSymbol value: a] ifFalse: [(aSortBlockOrSymbol value: a) < (aSortBlockOrSymbol value: b)]]] ifFalse: [[:a :b | aSortBlockOrSymbol cull: a cull: b]]
BTW the previous versions had a bug where it fails when called on an empty collection as the true/false check is done eagerly.
Cheers Carlo
-- View this message in context: http://forum.world.st/Sort-by-property-tp4748500p4748757.html Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
It's ultra-easy to port, I gave it a try at MCHttpRepository location: 'http://smalltalkhub.com/mc/nice/NiceVMExperiments/main' user: '' password: '' See packages TAG-SortFunctions and TAG-SortFunctionsTests Travis didn't mention the license, so we'll have to ask him. 2014-03-12 13:52 GMT+01:00 Esteban A. Maringolo <emaringolo@gmail.com>:
Is this multisort feature available for Pharo somewhere?
Regards!
Esteban A. Maringolo
2014-03-12 7:45 GMT-03:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>:
I presume you all know about Griggs work on the subject
http://stackoverflow.com/questions/8204826/smalltalk-sort-a-collection-by-tw...
http://objology.blogspot.com/2010/11/tag-sortfunctions.html
2014-03-12 11:23 GMT+01:00 carlo.t <snoobabk@yahoo.ie>:
Hi Otto
I think the main reason is to support the second usage scenario: SequenceableCollection withAllSubclasses sortedAs: [:class | class methodDict size]. We could try and unify the sort: method to take only blocks while sortedAs: a symbol but then at the same time we could just put everything into one method and use cull: perhaps to handle all the scenarios.
Personally I don't feel too comfortable with the code below, apart from the performance penalties it also feels like code that is too 'clever' for itself which obviously makes it complicated to understand and modify. I wrote it mainly for people to voice opinions and get ideas flowing. I'd have 2 separate sort methods so that users can choose if they want the runtime characteristics of either.
Example which can handle all current scenarios i.e. symbol or block taking 1 or 2 arguments: SequenceableCollection>>sort: aSortBlock self mergeSortFrom: 1 to: self size by: (self createSortBlock: aSortBlock)
SequenceableCollection>>createSortBlock: aSortBlockOrSymbol ^ aSortBlockOrSymbol numArgs < 2 ifTrue: [[ :a :b | (#(true false ) includes: (aSortBlockOrSymbol value: a)) ifTrue: [ aSortBlockOrSymbol value: a] ifFalse: [(aSortBlockOrSymbol value: a) < (aSortBlockOrSymbol value: b)]]] ifFalse: [[:a :b | aSortBlockOrSymbol cull: a cull: b]]
BTW the previous versions had a bug where it fails when called on an empty collection as the true/false check is done eagerly.
Cheers Carlo
-- View this message in context: http://forum.world.st/Sort-by-property-tp4748500p4748757.html Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
Exactly! Essentially, value: should replace pretty much all usages of perform:. For example, if Morphic would use value: variants instead of perform: we could script them without being obliged to create model classes. It would serve the spirit of fast prototyping much better. Cheers, Doru On Tue, Mar 11, 2014 at 11:54 PM, Carlo <snoobabk@gmail.com> wrote:
Hi
Since Symbol and Blocks are polymorphic could we not simplify the code to be:
SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlockOrSymbol. The receiver cannot be empty. Answer a new collection. This method does not side effect the receiver. e.g. SequenceableCollection withAllSubclasses sortedAs: #name. SequenceableCollection withAllSubclasses sortedAs: [:class | class methodDict size]." | aSortBlock | aSortBlock := (#(true false ) includes: (aSortBlockOrSymbol value: self first)) ifTrue: [[:a :b | aSortBlockOrSymbol value: a]] ifFalse: [[:a :b | (aSortBlockOrSymbol value: a) < (aSortBlockOrSymbol value: b)]]. ^ (SortedCollection new: self size) sortBlock: aSortBlock; addAll: self; yourself
Cheers Carlo
On 12 Mar 2014, at 12:32 AM, Pharo4Stef <pharo4Stef@free.fr> wrote:
Thanks eliot.
On 11 Mar 2014, at 20:51, Eliot Miranda <eliot.miranda@gmail.com> wrote:
and here's one with a better comment that includes examples
On Tue, Mar 11, 2014 at 12:19 PM, Eliot Miranda <eliot.miranda@gmail.com>wrote:
Hi Alexandre,
IMO the isKindOf:, apart from being ugly, will hurt performance badly. Why not apply aSortBlockOrSymbol to the first element and then choose the block appropriately? e.g.
aSortBlockOrSymbol isSymbol ifTrue: [(#(true false) includes: (self first perform: aSortBlockOrSymbol) ifTrue: [[:a :b | (a perform: aSortBlockOrSymbol)]] ifFalse: [[:a :b | (a perform: aSortBlockOrSymbol) < (b perform: aSortBlockOrSymbol)]]] ...
Nicer to read and faster, no?
On Tue, Mar 11, 2014 at 8:17 AM, Alexandre Bergel < alexandre.bergel@me.com> wrote:
hi Uko,
For Roassal, we have a #sortedAs: defined on all collections
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect"
| aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4)
Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag ...)
This is really handy. It should be part of Pharo I believe.
Cheers, Alexandre
On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe I'm wrong, but as I've told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
-- best, Eliot
-- best, Eliot <SequenceableCollection-sortedAs.st>
-- www.tudorgirba.com "Every thing has its own flow"
We could indeed, but it offends my sense of value (excuse the pun), since Symbol>>value: is implemented in terms of #perform: and so is slower. Since this is a general library routine performance is an issue (the sort block is used N log N times in sorting the collection) and so I prefer the use of perform: when the arg is a symbol and value: when it's a block. Eliot (phone) On Mar 11, 2014, at 3:54 PM, Carlo <snoobabk@gmail.com> wrote:
Hi
Since Symbol and Blocks are polymorphic could we not simplify the code to be:
SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlockOrSymbol. The receiver cannot be empty. Answer a new collection. This method does not side effect the receiver. e.g. SequenceableCollection withAllSubclasses sortedAs: #name. SequenceableCollection withAllSubclasses sortedAs: [:class | class methodDict size]." | aSortBlock | aSortBlock := (#(true false ) includes: (aSortBlockOrSymbol value: self first)) ifTrue: [[:a :b | aSortBlockOrSymbol value: a]] ifFalse: [[:a :b | (aSortBlockOrSymbol value: a) < (aSortBlockOrSymbol value: b)]]. ^ (SortedCollection new: self size) sortBlock: aSortBlock; addAll: self; yourself
<SequenceableCollection-sortedAs.st>
Cheers Carlo
On 12 Mar 2014, at 12:32 AM, Pharo4Stef <pharo4Stef@free.fr> wrote:
Thanks eliot.
On 11 Mar 2014, at 20:51, Eliot Miranda <eliot.miranda@gmail.com> wrote:
and here's one with a better comment that includes examples
On Tue, Mar 11, 2014 at 12:19 PM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi Alexandre,
IMO the isKindOf:, apart from being ugly, will hurt performance badly. Why not apply aSortBlockOrSymbol to the first element and then choose the block appropriately? e.g.
aSortBlockOrSymbol isSymbol ifTrue: [(#(true false) includes: (self first perform: aSortBlockOrSymbol) ifTrue: [[:a :b | (a perform: aSortBlockOrSymbol)]] ifFalse: [[:a :b | (a perform: aSortBlockOrSymbol) < (b perform: aSortBlockOrSymbol)]]] ...
Nicer to read and faster, no?
On Tue, Mar 11, 2014 at 8:17 AM, Alexandre Bergel <alexandre.bergel@me.com> wrote:
hi Uko,
For Roassal, we have a #sortedAs: defined on all collections
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SequenceableCollection>>sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect"
| aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You can use it for example: (1 to: 4) sortedAs: #odd => a SortedCollection(1 3 2 4)
Collection withAllSubclasses sortedAs: #numberOfMethods => a SortedCollection(HashBag IdentityHashBag â¦)
This is really handy. It should be part of Pharo I believe.
Cheers, Alexandre
On Mar 11, 2014, at 5:19 AM, Yuriy Tymchuk <yuriy.tymchuk@me.com> wrote:
Hi guys.
This is a thing that I encounter quite often.
Eg I have a collection of projects and I want to sort them by creation date. It would be nice to be able to do something like:
projects sortByProp: #creationDate
or by birth date of the author
projects sortByProp: [ :proj | proj author birthDate ]
Maybe Iâm wrong, but as Iâve told already I encounter it quite often and writing something like
projects sortBy: [ :prev :next | prev creationDate <= next creationDate ]
is boring for me.
Cheers. Uko
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
-- best, Eliot
-- best, Eliot <SequenceableCollection-sortedAs.st>
participants (4)
-
Alexandre Bergel -
Camille Teruel -
Carlo -
carlo.t -
Clément Bera -
Eliot Miranda -
Esteban A. Maringolo -
Nicolas Cellier -
Otto Behrens -
Pharo4Stef -
Tudor Girba -
Yuriy Tymchuk