You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Drew Davidson <dr...@ognl.org> on 2004/08/26 02:21:51 UTC
New OGNL list operators: sorting
I have been refactoring the OGNL parser for 2.7.0 (so that OGNL 3 will
share the same parser with OGNL 2) and I added a sorting operator to the
list operators. I've been wanting to scratch this itch for some time.
Many is the time when I wanted a sorted list and had to delegate to some
Java method to do it; usually it was a simple sort that didn't deserve
the infrastructure of a complicated Java method.
Here are a few examples of how it can be used
someList.{< #this }
Sort ascending the list of objects by comparing them against
each other (i.e. list of Integers, Dates, etc. - anything that
implements Comparable).
someList.{< name }
Sort ascending by comparing "name" properties of both
objects in the list.
someList.{> name }
Sort descending by comparing "name" properties of both
objects in the list.
someList.{> orderDate, name }
Sort descending by comparing "orderDate" property; if
orderDate is equal in both objects then sub-sort the elements by "name"
property. Both are descending order.
someList.{< name, :[ [0].orderDate.compareTo([1].orderDate) ] }
Sort ascending by name, then by the expression given
(ascending sense selected so compareTo() will work exactly as specified).
someList.{< name, :[ -[0].orderDate.compareTo([1].orderDate) ] }
Sort ascending by name, then by the expression given
(ascending sense selected so the compareTo() result will be negated,
thus making the secondary sort effectively descending).
The simple case of sorting a list by some expression both have in common
looks simple; you can specify ascending or descending and the expression
that retreives an object from each that implements Comparable (if they
are not Comparable then an exception is thrown).
The more complicated case is for those who want to monkey with the sort
order or do more complicated sorts, like reversing the sense of the
ascending/descending by returning a different value from the
expression. The last example above, for example, performs a compareTo()
and negates the result. This effectively changes the sense of the sort
operation from ascending to descending only for the subsort comparison.
The complicated case specifies a lambda expression; the sort node will
pass both comparison objects to this expression as an array of 2
elements. From there you can do anything you wish that returns an
integer (or anything that can be converted to an integer), the result
being used in the same fashion as the integer Comparable.compareTo()
result (i.e. 0 is equal, 1 is left is greater than right, -1 is left is
less than right).
This is useful when you want to use comparators that are external to the
objects themselves; a common case is Collator for doing string comparison:
#collator = @java.text.Collator@getInstance(),
#collator.strength = @java.text.Collator@PRIMARY,
sortedByName = objects.{< :[ #collator.compare([0].name, [1].name) ] }
The key here is that the simple case stays simple and understandable and
the syntax is available to let you do more complicated, dynamic stuff
(like, for example, if you want to present search panel in an
application and let the user choose the sort order and fields to sort on
- you can encapsulate the sort in the OGNL expression and leave the
comparison up to another object).
What does everyone think? Is this too complicated or bizarre? Is it
worth adding to the OGNL language?
- Drew
--
+---------------------------------+
< Drew Davidson | OGNL Technology >
+---------------------------------+
| Email: drew@ognl.org /
| Web: http://www.ognl.org /
| Vox: (520) 531-1966 <
| Fax: (520) 531-1965 \
| Mobile: (520) 405-2967 \
+---------------------------------+
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: New OGNL list operators: sorting
Posted by Jamie Orchard-Hays <ja...@dang.com>.
That's definitely useful. The complex sort does look a bit arcane, but it's
understandable.
Jamie
----- Original Message -----
From: "Drew Davidson" <dr...@ognl.org>
To: <og...@lists.ognl.org>; <og...@lists.ognl.org>;
"Tapestry users" <ta...@jakarta.apache.org>
Sent: Wednesday, August 25, 2004 8:21 PM
Subject: New OGNL list operators: sorting
> I have been refactoring the OGNL parser for 2.7.0 (so that OGNL 3 will
> share the same parser with OGNL 2) and I added a sorting operator to the
> list operators. I've been wanting to scratch this itch for some time.
> Many is the time when I wanted a sorted list and had to delegate to some
> Java method to do it; usually it was a simple sort that didn't deserve
> the infrastructure of a complicated Java method.
>
> Here are a few examples of how it can be used
>
> someList.{< #this }
> Sort ascending the list of objects by comparing them against
> each other (i.e. list of Integers, Dates, etc. - anything that
> implements Comparable).
>
> someList.{< name }
> Sort ascending by comparing "name" properties of both
> objects in the list.
>
> someList.{> name }
> Sort descending by comparing "name" properties of both
> objects in the list.
>
> someList.{> orderDate, name }
> Sort descending by comparing "orderDate" property; if
> orderDate is equal in both objects then sub-sort the elements by "name"
> property. Both are descending order.
>
> someList.{< name, :[ [0].orderDate.compareTo([1].orderDate) ] }
> Sort ascending by name, then by the expression given
> (ascending sense selected so compareTo() will work exactly as specified).
>
> someList.{< name, :[ -[0].orderDate.compareTo([1].orderDate) ] }
> Sort ascending by name, then by the expression given
> (ascending sense selected so the compareTo() result will be negated,
> thus making the secondary sort effectively descending).
>
> The simple case of sorting a list by some expression both have in common
> looks simple; you can specify ascending or descending and the expression
> that retreives an object from each that implements Comparable (if they
> are not Comparable then an exception is thrown).
>
> The more complicated case is for those who want to monkey with the sort
> order or do more complicated sorts, like reversing the sense of the
> ascending/descending by returning a different value from the
> expression. The last example above, for example, performs a compareTo()
> and negates the result. This effectively changes the sense of the sort
> operation from ascending to descending only for the subsort comparison.
> The complicated case specifies a lambda expression; the sort node will
> pass both comparison objects to this expression as an array of 2
> elements. From there you can do anything you wish that returns an
> integer (or anything that can be converted to an integer), the result
> being used in the same fashion as the integer Comparable.compareTo()
> result (i.e. 0 is equal, 1 is left is greater than right, -1 is left is
> less than right).
>
> This is useful when you want to use comparators that are external to the
> objects themselves; a common case is Collator for doing string comparison:
>
> #collator = @java.text.Collator@getInstance(),
> #collator.strength = @java.text.Collator@PRIMARY,
> sortedByName = objects.{< :[ #collator.compare([0].name, [1].name) ] }
>
> The key here is that the simple case stays simple and understandable and
> the syntax is available to let you do more complicated, dynamic stuff
> (like, for example, if you want to present search panel in an
> application and let the user choose the sort order and fields to sort on
> - you can encapsulate the sort in the OGNL expression and leave the
> comparison up to another object).
>
> What does everyone think? Is this too complicated or bizarre? Is it
> worth adding to the OGNL language?
>
> - Drew
>
> --
> +---------------------------------+
> < Drew Davidson | OGNL Technology >
> +---------------------------------+
> | Email: drew@ognl.org /
> | Web: http://www.ognl.org /
> | Vox: (520) 531-1966 <
> | Fax: (520) 531-1965 \
> | Mobile: (520) 405-2967 \
> +---------------------------------+
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
RE: New OGNL list operators: sorting
Posted by Nicholas Lesiecki <nl...@vmsinfo.com>.
I think it's a great idea. Bring it on.
--nick
-----Original Message-----
From: Drew Davidson [mailto:drew@ognl.org]
Sent: Wednesday, August 25, 2004 5:22 PM
To: ognl-interest@lists.ognl.org; ognl-developer@lists.ognl.org; Tapestry
users
Subject: New OGNL list operators: sorting
I have been refactoring the OGNL parser for 2.7.0 (so that OGNL 3 will
share the same parser with OGNL 2) and I added a sorting operator to the
list operators. I've been wanting to scratch this itch for some time.
Many is the time when I wanted a sorted list and had to delegate to some
Java method to do it; usually it was a simple sort that didn't deserve
the infrastructure of a complicated Java method.
Here are a few examples of how it can be used
someList.{< #this }
Sort ascending the list of objects by comparing them against
each other (i.e. list of Integers, Dates, etc. - anything that
implements Comparable).
someList.{< name }
Sort ascending by comparing "name" properties of both
objects in the list.
someList.{> name }
Sort descending by comparing "name" properties of both
objects in the list.
someList.{> orderDate, name }
Sort descending by comparing "orderDate" property; if
orderDate is equal in both objects then sub-sort the elements by "name"
property. Both are descending order.
someList.{< name, :[ [0].orderDate.compareTo([1].orderDate) ] }
Sort ascending by name, then by the expression given
(ascending sense selected so compareTo() will work exactly as specified).
someList.{< name, :[ -[0].orderDate.compareTo([1].orderDate) ] }
Sort ascending by name, then by the expression given
(ascending sense selected so the compareTo() result will be negated,
thus making the secondary sort effectively descending).
The simple case of sorting a list by some expression both have in common
looks simple; you can specify ascending or descending and the expression
that retreives an object from each that implements Comparable (if they
are not Comparable then an exception is thrown).
The more complicated case is for those who want to monkey with the sort
order or do more complicated sorts, like reversing the sense of the
ascending/descending by returning a different value from the
expression. The last example above, for example, performs a compareTo()
and negates the result. This effectively changes the sense of the sort
operation from ascending to descending only for the subsort comparison.
The complicated case specifies a lambda expression; the sort node will
pass both comparison objects to this expression as an array of 2
elements. From there you can do anything you wish that returns an
integer (or anything that can be converted to an integer), the result
being used in the same fashion as the integer Comparable.compareTo()
result (i.e. 0 is equal, 1 is left is greater than right, -1 is left is
less than right).
This is useful when you want to use comparators that are external to the
objects themselves; a common case is Collator for doing string comparison:
#collator = @java.text.Collator@getInstance(),
#collator.strength = @java.text.Collator@PRIMARY,
sortedByName = objects.{< :[ #collator.compare([0].name, [1].name) ] }
The key here is that the simple case stays simple and understandable and
the syntax is available to let you do more complicated, dynamic stuff
(like, for example, if you want to present search panel in an
application and let the user choose the sort order and fields to sort on
- you can encapsulate the sort in the OGNL expression and leave the
comparison up to another object).
What does everyone think? Is this too complicated or bizarre? Is it
worth adding to the OGNL language?
- Drew
--
+---------------------------------+
< Drew Davidson | OGNL Technology >
+---------------------------------+
| Email: drew@ognl.org /
| Web: http://www.ognl.org /
| Vox: (520) 531-1966 <
| Fax: (520) 531-1965 \
| Mobile: (520) 405-2967 \
+---------------------------------+
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
RE: New OGNL list operators: sorting
Posted by Patrick Lightbody <pl...@yahoo.com>.
I think sorting would be a good thing, but I do admit I'm getting very
confused about the various collection notations that would now be
available. Can you detail projection, sorting, etc?
> -----Original Message-----
> From: Drew Davidson [mailto:drew@ognl.org]
> Sent: Wednesday, August 25, 2004 5:22 PM
> To: ognl-interest@lists.ognl.org; ognl-developer@lists.ognl.org;
Tapestry
> users
> Subject: New OGNL list operators: sorting
>
> I have been refactoring the OGNL parser for 2.7.0 (so that OGNL 3 will
> share the same parser with OGNL 2) and I added a sorting operator to
the
> list operators. I've been wanting to scratch this itch for some time.
> Many is the time when I wanted a sorted list and had to delegate to
some
> Java method to do it; usually it was a simple sort that didn't deserve
> the infrastructure of a complicated Java method.
>
> Here are a few examples of how it can be used
>
> someList.{< #this }
> Sort ascending the list of objects by comparing them
against
> each other (i.e. list of Integers, Dates, etc. - anything that
> implements Comparable).
>
> someList.{< name }
> Sort ascending by comparing "name" properties of both
> objects in the list.
>
> someList.{> name }
> Sort descending by comparing "name" properties of both
> objects in the list.
>
> someList.{> orderDate, name }
> Sort descending by comparing "orderDate" property; if
> orderDate is equal in both objects then sub-sort the elements by
"name"
> property. Both are descending order.
>
> someList.{< name, :[ [0].orderDate.compareTo([1].orderDate) ] }
> Sort ascending by name, then by the expression given
> (ascending sense selected so compareTo() will work exactly as
specified).
>
> someList.{< name, :[ -[0].orderDate.compareTo([1].orderDate) ] }
> Sort ascending by name, then by the expression given
> (ascending sense selected so the compareTo() result will be negated,
> thus making the secondary sort effectively descending).
>
> The simple case of sorting a list by some expression both have in
common
> looks simple; you can specify ascending or descending and the
expression
> that retreives an object from each that implements Comparable (if they
> are not Comparable then an exception is thrown).
>
> The more complicated case is for those who want to monkey with the
sort
> order or do more complicated sorts, like reversing the sense of the
> ascending/descending by returning a different value from the
> expression. The last example above, for example, performs a
compareTo()
> and negates the result. This effectively changes the sense of the sort
> operation from ascending to descending only for the subsort
comparison.
> The complicated case specifies a lambda expression; the sort node will
> pass both comparison objects to this expression as an array of 2
> elements. From there you can do anything you wish that returns an
> integer (or anything that can be converted to an integer), the result
> being used in the same fashion as the integer Comparable.compareTo()
> result (i.e. 0 is equal, 1 is left is greater than right, -1 is left
is
> less than right).
>
> This is useful when you want to use comparators that are external to
the
> objects themselves; a common case is Collator for doing string
comparison:
>
> #collator = @java.text.Collator@getInstance(),
> #collator.strength = @java.text.Collator@PRIMARY,
> sortedByName = objects.{< :[ #collator.compare([0].name, [1].name)
] }
>
> The key here is that the simple case stays simple and understandable
and
> the syntax is available to let you do more complicated, dynamic stuff
> (like, for example, if you want to present search panel in an
> application and let the user choose the sort order and fields to sort
on
> - you can encapsulate the sort in the OGNL expression and leave the
> comparison up to another object).
>
> What does everyone think? Is this too complicated or bizarre? Is it
> worth adding to the OGNL language?
>
> - Drew
>
> --
> +---------------------------------+
> < Drew Davidson | OGNL Technology >
> +---------------------------------+
> | Email: drew@ognl.org /
> | Web: http://www.ognl.org /
> | Vox: (520) 531-1966 <
> | Fax: (520) 531-1965 \
> | Mobile: (520) 405-2967 \
> +---------------------------------+
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ognl-developer-unsubscribe@lists.ognl.org
> For additional commands, e-mail: ognl-developer-help@lists.ognl.org
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org