-1

I have the following NSArray which contains a dictionary at each index , here is the content, just providing first 3 records-

[
            {

                "postDate": "4/11/2011 2:03:33 PM",
                "imageLink": "",
                "eventLink": "www.google.com"
            },
            {

                "postDate": "6/16/2011 1:42:45 PM",
                "imageLink": "",
                "eventLink": "www.google.com"
            },
            {

                "postDate": "9/21/2011 10:22:34 AM",
                "imageLink": "",
                "eventLink": "www.google.com"
            }
]

NOTE:- postDate is just a NSString it is not coming in NSDate type, but I have to perform sort on basis of this key.

My task is to sort the array as per the "postDate" key , means the whole array will be sorted in order by date (ascending/descending).

I have used the following code, but didn't help as arr is storing the all the data from arrEventsData but sorting is not happening:-

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"postDate"  ascending:YES];

    NSMutableArray *arr = [[arrEventsData sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy]; 

Any idea or solution will help.

Thanks

Vizllx
  • 9,135
  • 1
  • 41
  • 79

3 Answers3

4
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"M/dd/yyyy H:mm:ss a"];

NSArray *sortedByDates = [arr sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2)
{
    NSDate *date1 = [dateFormatter dateFromString:obj1[@"postDate"]];
    NSDate *date2 = [dateFormatter dateFromString:obj2[@"postDate"]];
    return [date1 compare:date2];
}];
NSLog(@"Sorted Array : %@",sortedByDates);
Dipen Panchasara
  • 13,480
  • 5
  • 47
  • 57
2

Like this:

    NSMutableArray *sortedArray = [arr sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
        NSDate *d1 = [self stringToDate:obj1[@"postDate"]];
        NSDate *d2 = [self stringToDate:obj2[@"postDate"]];
        return [d1 compare:d2];
    }];

For the "stringToDate" method, however you want to implement that, see another SO answer here: Convert NSString of a date to an NSDate

Edit: As @Droppy has pointed out, it would really be best to parse the string into a NSDate as soon as the data arrives from the server. That prevents expensive repeated conversion in sorting, and is probably all around more useful anyway.

Community
  • 1
  • 1
n13
  • 6,843
  • 53
  • 40
  • I'm sure that will work, but the repeated conversion of string to date will make it expensive. – Droppy May 27 '15 at 10:42
  • (even more so if you follow the code you linked and create a new `NSDateFormatter` each time). – Droppy May 27 '15 at 10:43
  • Sure. But it depends on how many records you have whether or not that would cause a problem. If it did, there's numerous ways to cache the conversion. Not doing that for him either ;) – n13 May 27 '15 at 10:44
  • ... like converting the data to a custom object as soon as it's parsed, for example? – Droppy May 27 '15 at 10:46
  • Yes that's one option. Spend as much time as you need to make the stringToDate method as fast and as efficient as you need. I wouldn't bother at all if I process, say, 10 records at a time. If theres 100, maybe. If there's 1000, sure. – n13 May 27 '15 at 10:47
  • @Droppy that's a good idea - maybe. It really depends on the problem space which we don't know anything about. I didn't want to go too overboard with this solution. Just to show how to sort an array of dicts. – n13 May 27 '15 at 10:50
  • Well the OP has already hit one issue by keeping the data in the form it was delivered in (via JSON I guess). People do not seem to appreciate the time saved by creating a custom Model object for their data. Oh well, their loss... – Droppy May 27 '15 at 10:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/78886/discussion-between-n13-and-droppy). – n13 May 27 '15 at 10:52
0

You will have to create NSDate objects from those NSString's to make the compare work

Create a static NSDateFormatter as they are expensive to create:

NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *a, NSDictionary *b) {

        static NSDateFormatter *dateFormatter = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; //Set correct format here
        });

        NSDate *first = [dateFormatter dateFromString:[a objectForKey:@"postDate"]];
        NSDate *second = [dateFormatter dateFromString:[b objectForKey:@"postDate"]];
        return [first compare:second];
    }];
Jasper
  • 7,031
  • 3
  • 35
  • 43