Custom compare: for NSDate sort descriptor

  • This seems like a basic question but my searches aren't helping...

    I have a table column with NSDate values. I simply want to sort
    "blank" dates AFTER the last date rather than before the earliest
    date (which is the behavior of the standard compare:).

    From what I can tell, the best route would be to add a category to
    NSDate and implement a custom compare: method?

    Or I suppose I could make an NSDate subclass to put the custom
    compare:? However, it's a Core Data attribute so I'm not sure if that
    makes it difficult or not.

    Just wondering if there is a standard approach before I spend time on
    either of the above.

    My mind is a bit of spaghetti right now having run into several
    roadblocks today so I apologize if I'm overlooking something obvious.

    Thanks!
    George
  • on 10/8/07 5:07 PM, <george.o...> purportedly said:

    > I have a table column with NSDate values. I simply want to sort
    > "blank" dates AFTER the last date rather than before the earliest
    > date (which is the behavior of the standard compare:).
    >
    > From what I can tell, the best route would be to add a category to
    > NSDate and implement a custom compare: method?

    Probably, but don't override -compare:. Instead, create a custom method and
    use sort descriptors.

    Best,

    Keary Suska
    Esoteritech, Inc.
    "Demystifying technology for your home or business"
  • Solved! But not with a category after all. :)

    I first implemented a category but found that nil date values weren't
    being sent to my custom compare method at all! Quite a problem. I
    searched a bit and did find a thread where the poster had created a
    custom NSSortDescriptor subclass... he couldn't quite remember why he
    didn't use a custom compare method and I suspect it was because of
    these nil values.
    http://www.cocoabuilder.com/archive/message/cocoa/2006/7/5/166885

    Luckily the last post in the thread had another suggestion. Create a
    dummy key that filters out the nil values into NSNull objects that
    can be compared. Well I immediately found that my custom compare
    category only applied to NSDate and not NSNull. However, I had it
    together enough this morning to put 2 and 2 together into a more
    elegant solution:

    - (id)sortableValueForDueDate
    {
    id value = [self valueForKey:@"due_date"];
    if (value==nil)
      value = [NSDate distantFuture];
    return (value);
    }

    I let the normal compare: do its work, by replacing nil values with
    distantFuture (which is coming up as 1-1-4001 if you ever wondered).

    Thanks to Keary Suska for keeping me moving and to the list archives
    as well. The solution ended up being simple, but why is the journey
    so difficult? :P

    George
  • On Oct 9, 2007, at 07:46, George Orthwein wrote:

    > Solved! But not with a category after all. :)
    >
    > I first implemented a category but found that nil date values
    > weren't being sent to my custom compare method at all! Quite a
    > problem. I searched a bit and did find a thread where the poster had
    > created a custom NSSortDescriptor subclass... he couldn't quite
    > remember why he didn't use a custom compare method and I suspect it
    > was because of these nil values.
    > http://www.cocoabuilder.com/archive/message/cocoa/2006/7/5/166885

    Being the OP of that thread, I'll just mention that I did work around
    the performance problems and bugs inherent in subclassing
    NSSortDescriptor.  It required implementing my own version of -
    [NSMutableArray sortUsingDescriptors:] (using mergesort and caching,
    probably similar to what Apple does) but avoids the problems with
    compareObject:toObject:.  BSD licensed code's available at <http://bibdesk.svn.sourceforge.net/viewvc/bibdesk/trunk/bibdesk/NSArray_BDS
    KExtensions.m?revision=11217&view=markup
    >, but I'd avoid the approach if at all possible.

    --
    adam
  • One followup, I was getting the error on startup:

    *** NSRunLoop ignoring exception 'Unknown key in query.
    sortableValueForDueDate' that raised during posting of delayed
    perform with target 15988be0 and selector 'invokeWithTarget:'

    I had to add "sortableValueForDueDate" as a transient property in my
    Core Data model as suggested here:
    http://www.cocoabuilder.com/archive/message/cocoa/2007/3/15/180343

    The problem is further detailed in that thread as well.

    George
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today