Sort NSArray with custom objects
Asked Answered
H

4

8

In my Xcode project I have the following classes:

Address

@interface LDAddress : NSObject{
    NSString *street;
    NSString *zip;
    NSString *city;
    float latitude;
    float longitude;
}

@property (nonatomic, retain) NSString *street;
@property (nonatomic, retain) NSString *zip;
@property (nonatomic, retain) NSString *city;
@property (readwrite, assign, nonatomic) float latitude;
@property (readwrite, assign, nonatomic) float longitude;

@end

Location

@interface LDLocation : NSObject{
    int locationId;
    NSString *name;
    LDAddress *address;
}
@property (readwrite, assign, nonatomic) int locationId;
@property (nonatomic, retain) LDAddress *address;
@property (nonatomic, retain) NSString *name;

@end

In an subclass of UITableViewController, there is a NSArray containing a lot of unsorted objects of LDLocations. Now, I want to sort the NSArray's objects ascending based on the property city of a LDAddress.

How can I sort the array using NSSortDescriptor? I tried the following, but the app dumps when sorting the array.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Address.city" ascending:YES];
[_locations sortedArrayUsingDescriptors:@[sortDescriptor]];
Hensel answered 1/6, 2012 at 15:41 Comment(1)
have you tried just @"city" as the key?Overarch
F
14

Try making the first key lowercase.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"address.city" ascending:YES];
Fatalism answered 1/6, 2012 at 15:47 Comment(0)
Y
14

You can also sort an array with blocks:

    NSArray *sortedLocations = [_locations sortedArrayUsingComparator: ^(LDAddress *a1, LDAddress *a2) {
        return [a1.city compare:a2.city];
    }];
Yabber answered 1/6, 2012 at 15:49 Comment(1)
I tried your coding and it worked, but I like sorting an array with NSSortDescriptor more.Hensel
C
3

This will allow to sort with multiple types. Like we need to sort the Movie based on time and if the time is equal then need to sort by name.

NSArray *sortedArray = [childrenArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSNumber *first = [NSNumber numberWithLong:[(Movie*)a timeInMillis]];
        NSNumber *second = [NSNumber numberWithLong:[(Movie*)b timeInMillis]];
        NSComparisonResult result =  [first compare:second];
        if(result == NSOrderedSame){
            result = [((NSString*)[(Movie*)a name] ) compare:((NSString*)[(Movie*)b name])];
        }
        return  result;
    }];
Cuirbouilli answered 1/8, 2014 at 10:28 Comment(0)
W
1
-(NSArray*)sortedWidgetList:(NSArray*)widgetList
{
    NSSortDescriptor *firstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"itemNum" ascending:YES];

    NSArray *sortDescriptors = [NSArray arrayWithObjects:firstDescriptor, nil];

    NSArray *sortedArray = [widgetList sortedArrayUsingDescriptors:sortDescriptors];

    return sortedArray;
}
Wolcott answered 18/5, 2015 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.