Re: Null values at end of sorted list
Re: Null values at end of sorted list
- Subject: Re: Null values at end of sorted list
- From: email@hidden
- Date: Thu, 31 Jan 2008 14:26:58 -0500
Hi James,
The ComparisonSupport becomes transparent
and used universally throughout the app. Here's an excerpt of one place
where a sort occurs:
NSMutableArray displayedObjects = <the
objects to display in a paginated list on the screen>
NSMutableArray sortOrderings = <a
list of EOSortOrdering objects taking a key and an NSSelector>
EOSortOrdering.sortArrayUsingKeyOrderArray(displayedObjects,
sortOrderings);
This is often called by clicking a little
toggle icon to modify the "sortOrderings" array with a particular
"key" and either "compareAscending" or "compareDescending".
It works like a charm. The null values
are placed at the very end of an ascending sort and placed at the beginning
of a descending sort. It works so long as we haven't done any commits to
the database. Sounds odd, I know, because I don't fully understand what
is happening. It probably isn't the commit to the database itself but some
other nuance. All I know with certainty is that I can move around the whole
app and happily re-sort columns anywhere but as soon as I do a commit I'm
no longer able to reliably sort columns on any page. Also, once it gets
in this bad state, any new wosessions I start exhibit the same problem
immediately.
-- Aaron
James Cicenia <email@hidden> wrote on 31-01-2008
02:01:03 PM:
> What do you mean it no longer works after commits?
>
> How are you using your comparator?
>
> -James Cicenia
>
> On Jan 31, 2008, at 12:34 PM, email@hidden wrote:
>
>
> What happens when you want to sort ten values in ascending order but
> one of them is null? Does that void value get put at the beginning,
> the middle, or the end?
>
> Apple decided that null values (or keyPaths that return a null
> value) should be placed at the beginning of an array sorted in
> ascending order. Perhaps they felt that "null is less than zero".
>
> For us, it seems that null values should be placed at the end of an
> ascending sort. More often than not, null values make more sense to
> be placed at the end of the list when working in our Domain.
>
> Has anyone crossed this bridge before?
>
> We've tried our hand at a solution which is listed at the bottom of
> this message. It works so long as no commits have been made to the
> database! After a commit, from any page in the app, sorting no
> longer works as expected and often results in a K2Sort error. It's
baffling.
>
> Our class extends the default sorting logic of EOSortOrdering.
> ComparisonSupport (the class that does sorting globally for WO). We
> really only want to override "handleNulls()" but because
it is both
> private and static, we need to redo a few other methods as well.
> Functionally, our class is identical but choose to place null values
> at the end of the list for an ascending sort.
>
> Here is the line we add to the Appliction's constructor to get the
> ball rolling globally:
> ==========================
>
> EOSortOrdering.ComparisonSupport.setSupportForClass(new
> CXNullsAtEndComparisonSupport(), Object.class);
>
>
> Here is the source code to the custom ComparisonSupport:
> ==========================
>
> public class CXNullsAtEndComparisonSupport extends EOSortOrdering.
> ComparisonSupport {
>
> public static final Logger _logger = Logger.
> getLogger(CXNullsAtEndComparisonSupport.class);
>
> public CXNullsAtEndComparisonSupport()
{}
>
> protected static final int kNeitherNull
= -42;
>
> protected static int handleNulls(Object
left, Object right)
> {
> if(left ==
null || left == NSKeyValueCoding.NullValue)
>
return right != null && right !=
> NSKeyValueCoding.NullValue ? NSComparator.OrderedDescending :
> NSComparator.OrderedSame;
> return right
!= null && right != NSKeyValueCoding.
> NullValue ? kNeitherNull : NSComparator.OrderedAscending;
> }
>
> private static final NSTimestampFormatter
> defaultStringTimestampFormatter = new NSTimestampFormatter("%Y-%m-%d
> %H:%M:%S %Z");
>
> protected static NSTimestamp coerceToTimestampClass(Object
value)
> {
> if(value instanceof
NSTimestamp)
>
return (NSTimestamp)value;
> if(value instanceof
Date)
>
return new NSTimestamp(((Date)value).getTime());
> if(value instanceof
Number)
>
return new NSTimestamp(((Number)value).longValue());
> try {
>
return (NSTimestamp)
> defaultStringTimestampFormatter.parseObject((String)value);
> } catch (Exception
e) {
>
//fixme: do something more.
>
_logger.info("coerceToTimestampClass failed.
> Message = " + e.getMessage());
>
return null;
> }
> }
>
> protected int _genericCompareTo(Object
left, Object right)
> {
> int nullCheck
= handleNulls(left, right);
> if(nullCheck
!= kNeitherNull) {
>
return nullCheck;
> }
> Class LHSClass
= left.getClass();
> if(LHSClass
== _NSUtilities._StringClass)
>
return left.toString().compareTo(right.toString());
> if((left instanceof
Number) || LHSClass ==
> _NSUtilities._BooleanClass)
>
return _NSUtilities.
> compareNumbersOrBooleans(left, right);
> if(left instanceof
Date)
> {
>
if(LHSClass != NSTimestamp._CLASS)
>
left = coerceToTimestampClass(left);
>
right = coerceToTimestampClass(right);
> }
> if(left instanceof
Comparable)
>
return ((Comparable)left).compareTo(right);
> else
>
return left.toString().compareTo(right.toString());
> }
>
> protected int _genericCaseInsensitiveCompareTo(Object
left,
> Object right)
> {
> int nullCheck
= handleNulls(left, right);
> if(nullCheck
!= kNeitherNull)
>
return nullCheck;
> Class LHSClass
= left.getClass();
> if(LHSClass
== _NSUtilities._StringClass)
>
return left.toString().
> compareToIgnoreCase(right.toString());
> if((left instanceof
Number) || LHSClass ==
> _NSUtilities._BooleanClass)
>
return _NSUtilities.
> compareNumbersOrBooleans(left, right);
> if(left instanceof
Date)
> {
>
if(LHSClass != NSTimestamp._CLASS)
>
left = coerceToTimestampClass(left);
>
right = coerceToTimestampClass(right);
>
return ((Comparable)left).compareTo(right);
> } else
> {
>
return left.toString().
> compareToIgnoreCase(right.toString());
> }
> }
>
> } _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden