Hello, I made a small library that reify grouping (that one does via #groupBy: usually): Grouper https://github.com/juliendelplanque/Grouper It is designed in the same spirit as SortFunction, but for grouping. Quick example: The following code snippet using Grouper: (10 to: 50)groupUsing: [:integer | integer asString first ]. "an OrderedDictionary( $1->#(10 11 12 13 14 15 16 17 18 19) $2->#(20 21 22 23 24 25 26 27 28 29) $3->#(30 31 32 33 34 35 36 37 38 39) $4->#(40 41 42 43 44 45 46 47 48 49) $5->#(50))" is equivalent to the following code snippet using built-in|#groupedBy:|method: (10 to: 50)groupedBy: [:integer | integer asString first ] "an OrderedDictionary( $1->#(10 11 12 13 14 15 16 17 18 19) $2->#(20 21 22 23 24 25 26 27 28 29) $3->#(30 31 32 33 34 35 36 37 38 39) $4->#(40 41 42 43 44 45 46 47 48 49) $5->#(50))" The advantage of using it is that it allows one to compose grouper objects. Thus, it is easy to describe grouping on 2 or 3 levels. Fore example: The power of Grouper is that group description are first-class objects. Thus, it is possible to compose group descriptions in order to group a flat collection on multiple levels. For example: groupComposition:= [:integer | integer asString first ] grouper , [:integer | integer asString second ]. (10 to: 50)groupUsing: groupComposition. "an OrderedDictionary( $1->an OrderedDictionary( $0->#(10) $1->#(11) $2->#(12) $3->#(13) $4->#(14) $5->#(15) $6->#(16) $7->#(17) $8->#(18) $9->#(19)) $2->an OrderedDictionary( $0->#(20) $1->#(21) $2->#(22) $3->#(23) $4->#(24) $5->#(25) $6->#(26) $7->#(27) $8->#(28) $9->#(29)) $3->an OrderedDictionary( $0->#(30) $1->#(31) $2->#(32) $3->#(33) $4->#(34) $5->#(35) $6->#(36) $7->#(37) $8->#(38) $9->#(39)) $4->an OrderedDictionary( $0->#(40) $1->#(41) $2->#(42) $3->#(43) $4->#(44) $5->#(45) $6->#(46) $7->#(47) $8->#(48) $9->#(49)) $5->an OrderedDictionary($0->#(50)))" On the github, there are more example showing how to build trees with custom objects. Any feedback for this library is welcome. I would like to propose it to Pharo in the near future because it would simplify a lot of code in DrTests (related to result tree views, the tree on the right of the UI). I don't know if it will be possible before next release as we are in feature freeze. Cheers, Julien
This is cool. Rails has this kind of capability and I miss it elsewhere.
On Dec 9, 2019, at 6:08 AM, Julien Delplanque <julien.delplanque@inria.fr> wrote:
Hello,
I made a small library that reify grouping (that one does via #groupBy: usually): Grouper https://github.com/juliendelplanque/Grouper <https://github.com/juliendelplanque/Grouper> It is designed in the same spirit as SortFunction, but for grouping.
Quick example:
The following code snippet using Grouper:
(10 to: 50) groupUsing: [ :integer | integer asString first ]. "an OrderedDictionary( $1->#(10 11 12 13 14 15 16 17 18 19) $2->#(20 21 22 23 24 25 26 27 28 29) $3->#(30 31 32 33 34 35 36 37 38 39) $4->#(40 41 42 43 44 45 46 47 48 49) $5->#(50))" is equivalent to the following code snippet using built-in #groupedBy: method:
(10 to: 50) groupedBy: [ :integer | integer asString first ] "an OrderedDictionary( $1->#(10 11 12 13 14 15 16 17 18 19) $2->#(20 21 22 23 24 25 26 27 28 29) $3->#(30 31 32 33 34 35 36 37 38 39) $4->#(40 41 42 43 44 45 46 47 48 49) $5->#(50))" The advantage of using it is that it allows one to compose grouper objects.
Thus, it is easy to describe grouping on 2 or 3 levels.
Fore example:
The power of Grouper is that group description are first-class objects. Thus, it is possible to compose group descriptions in order to group a flat collection on multiple levels.
For example:
groupComposition := [ :integer | integer asString first ] grouper , [ :integer | integer asString second ]. (10 to: 50) groupUsing: groupComposition. "an OrderedDictionary( $1->an OrderedDictionary( $0->#(10) $1->#(11) $2->#(12) $3->#(13) $4->#(14) $5->#(15) $6->#(16) $7->#(17) $8->#(18) $9->#(19)) $2->an OrderedDictionary( $0->#(20) $1->#(21) $2->#(22) $3->#(23) $4->#(24) $5->#(25) $6->#(26) $7->#(27) $8->#(28) $9->#(29)) $3->an OrderedDictionary( $0->#(30) $1->#(31) $2->#(32) $3->#(33) $4->#(34) $5->#(35) $6->#(36) $7->#(37) $8->#(38) $9->#(39)) $4->an OrderedDictionary( $0->#(40) $1->#(41) $2->#(42) $3->#(43) $4->#(44) $5->#(45) $6->#(46) $7->#(47) $8->#(48) $9->#(49)) $5->an OrderedDictionary($0->#(50)))" On the github, there are more example showing how to build trees with custom objects.
Any feedback for this library is welcome.
I would like to propose it to Pharo in the near future because it would simplify a lot of code in DrTests (related to result tree views, the tree on the right of the UI).
I don't know if it will be possible before next release as we are in feature freeze.
Cheers,
Julien
Pretty cool! Alexandre http://bergel.eu
Le 9 déc. 2019 à 11:10, Julien Delplanque <julien.delplanque@inria.fr> a écrit :
 Hello,
I made a small library that reify grouping (that one does via #groupBy: usually): Grouper https://github.com/juliendelplanque/Grouper
It is designed in the same spirit as SortFunction, but for grouping.
Quick example:
The following code snippet using Grouper:
(10 to: 50) groupUsing: [ :integer | integer asString first ]. "an OrderedDictionary( $1->#(10 11 12 13 14 15 16 17 18 19) $2->#(20 21 22 23 24 25 26 27 28 29) $3->#(30 31 32 33 34 35 36 37 38 39) $4->#(40 41 42 43 44 45 46 47 48 49) $5->#(50))" is equivalent to the following code snippet using built-in #groupedBy: method:
(10 to: 50) groupedBy: [ :integer | integer asString first ] "an OrderedDictionary( $1->#(10 11 12 13 14 15 16 17 18 19) $2->#(20 21 22 23 24 25 26 27 28 29) $3->#(30 31 32 33 34 35 36 37 38 39) $4->#(40 41 42 43 44 45 46 47 48 49) $5->#(50))" The advantage of using it is that it allows one to compose grouper objects.
Thus, it is easy to describe grouping on 2 or 3 levels.
Fore example:
The power of Grouper is that group description are first-class objects. Thus, it is possible to compose group descriptions in order to group a flat collection on multiple levels.
For example:
groupComposition := [ :integer | integer asString first ] grouper , [ :integer | integer asString second ]. (10 to: 50) groupUsing: groupComposition. "an OrderedDictionary( $1->an OrderedDictionary( $0->#(10) $1->#(11) $2->#(12) $3->#(13) $4->#(14) $5->#(15) $6->#(16) $7->#(17) $8->#(18) $9->#(19)) $2->an OrderedDictionary( $0->#(20) $1->#(21) $2->#(22) $3->#(23) $4->#(24) $5->#(25) $6->#(26) $7->#(27) $8->#(28) $9->#(29)) $3->an OrderedDictionary( $0->#(30) $1->#(31) $2->#(32) $3->#(33) $4->#(34) $5->#(35) $6->#(36) $7->#(37) $8->#(38) $9->#(39)) $4->an OrderedDictionary( $0->#(40) $1->#(41) $2->#(42) $3->#(43) $4->#(44) $5->#(45) $6->#(46) $7->#(47) $8->#(48) $9->#(49)) $5->an OrderedDictionary($0->#(50)))" On the github, there are more example showing how to build trees with custom objects.
Any feedback for this library is welcome.
I would like to propose it to Pharo in the near future because it would simplify a lot of code in DrTests (related to result tree views, the tree on the right of the UI).
I don't know if it will be possible before next release as we are in feature freeze.
Cheers,
Julien
participants (3)
-
Alexandre Bergel -
Julien Delplanque -
Todd Blanchard