0

HI i have a following array of dictionaries and and i want to sort the array using the the key "BirthDate" and my code is as follows

NSLog(@"nodeEventArray == %@", temp);
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
                                    sortDescriptorWithKey:@"BirthDate"
                                    ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [temp
                             sortedArrayUsingDescriptors:sortDescriptors];
NSLog(@"sortedEventArray == %@", sortedEventArray);

but I was unable to sort properly can any one please tell me how to sort the array of dictionary based on "BirthDate" key .Since birth date is coming as string from service

sample array of dictionaries:

   nodeEventArray = (
        {
        BirthDate = "05/04/1986";
        Email = "";
        FirstName = Test;
        IsSpouse = 0;
        LastName = Test;
        MiddleInitial = "";
        PatientID = "";
        Phone = "";
        ScacntronCSVId = 40409;
        SlotID = 1;
        UserName = "Tes_02192013010055";
    },
        {
        BirthDate = "02/14/1986";
        Email = "";
        FirstName = Guest;
        IsSpouse = 0;
        LastName = Guest;
        MiddleInitial = "";
        PatientID = "";
        Phone = "";
        ScacntronCSVId = 40410;
        SlotID = 2;
        UserName = "Gue_02192013014725";
    },
        {
        BirthDate = "02/17/1987";
        Email = "";
        FirstName = User;
        IsSpouse = 0;
        LastName = User;
        MiddleInitial = "";
        PatientID = "";
        Phone = "";
        ScacntronCSVId = 40411;
        SlotID = 3;
        UserName = "Use_02192013020726";
    }
    )
Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167
user564963
  • 2,284
  • 5
  • 24
  • 33
  • Perhaps this is what you are looking for: [How to sort an NSMutableArray with custom objects in it?](http://stackoverflow.com/questions/805547/how-to-sort-an-nsmutablearray-with-custom-objects-in-it) – cacba Feb 19 '13 at 07:50
  • 1
    When you say "sort properly" what do you mean? The "BirthDate" is only a string and so it will sort in ascending alphabetical order. – Fogmeister Feb 19 '13 at 07:50
  • Yeah, why aren't you holding *BirthDate* using an `NSDate`? – trojanfoe Feb 19 '13 at 07:53

2 Answers2

1

I assume the array was coming from a server or something (hence the "Username" bit) but still, it would be better to store each user/event/whatever in an object with an NSDate. That way you can just sort by the date and it works.

However, if you want to sort this array then...

If you want to sort by BirthDate (using the date) then you'll need to convert the strings into actual NSDates.

NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateFormat = @"MM/dd/yyyy";

[blah sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
    NSDate *date1 = [df dateFromString:[obj1 objectForKey:@"BirthDate"];
    NSDate *date2 = [df dateFromString:[obj2 objectForKey:@"BirthDate"];

    return [date1 compare:date2];
}];

This should do it.

It will convert the strings into dates and then compare them.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • 1
    He's using the stupid american format `MM/dd/yy`, not the excellent UK format `dd/MM/yy` :D – trojanfoe Feb 19 '13 at 08:00
  • Although I would encourage him to use `NSDate` to store the date anyway, rather than convert to it temporarily, for the obvious benefits that brings. – trojanfoe Feb 19 '13 at 08:03
  • True, I assumed the array was coming from a server or something (hence the "Username" bit) but still, it would be better to store each user in an object with an NSDate. – Fogmeister Feb 19 '13 at 08:04
0

Instead of using sortDescriptor you can use comparator

NSArray *sortedArray = [nodeEventArray sortedArrayUsingComparator: ^(id obj1, id obj2) {
        NSDateFormatter *dateFormator = [[NSDateFormatter alloc] init];
        NSDate *date1 = [dateFormator dateFromString:[[obj1 objectForKey:@"BirthDate"] stringByReplacingOccurrencesOfString:[[obj1 objectForKey:@"BirthDate"] lastPathComponent] withString:@"2013"]];
        NSDate *date2 = [dateFormator dateFromString:[[obj1 objectForKey:@"BirthDate"] stringByReplacingOccurrencesOfString:[[obj1 objectForKey:@"BirthDate"] lastPathComponent] withString:@"2013"]];
        if ([date1 earlierDate:date2] == date1) {
            return (NSComparisonResult)NSOrderedDescending;
        }else{
            return (NSComparisonResult)NSOrderedAscending;
        }

    }];
Sunil Pandey
  • 7,042
  • 7
  • 35
  • 48
  • working fine but need ascending and descending sorting as well but its working for ascending only not for descending and need to sort with month and date also not only with year. – user564963 Feb 19 '13 at 09:43
  • I have modified my logic according to your requirement. Also if you swap the NSOrderedAscending and NSOrderedDescending then your sorting will be reversed – Sunil Pandey Feb 19 '13 at 12:55
  • thanks for you update ,i got it and for ascending and descending i am using as mentioned below if (dobSorted == YES) { //For Ascending Order return [[df dateFromString:[dict1 objectForKey:@"BirthDate"]] compare:[df dateFromString:[dict2 objectForKey:@"BirthDate"]]]; }else{ //For Desending Order return -1 *[[df dateFromString:[dict1 objectForKey:@"BirthDate"]] compare:[df dateFromString:[dict2 objectForKey:@"BirthDate"]]]; } – user564963 Feb 19 '13 at 13:39