Reputation: 38162
I have created a sort descriptor to sort a plist response coming from my server. This works well with sort key having values upto 9. With more than 10 items I see abrupt results with sort key arranged in the order = 1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort" ascending:YES];
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];
How to make it arrange in the correct order of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11?
Upvotes: 28
Views: 16740
Reputation: 1
input
{
"seats": [{
"seatNumber": "1"
}, {
"seatNumber": "10"
}, {
"seatNumber": "2"
}]
}
sort using [NSSortDescriptor sortDescriptorWithKey:@"seatNumber" ascending:YES selector:@selector(localizedStandardCompare:)]]. The key is to use localizedStandardCompare. This will solve you problem.
NSArray *seats = [self.seats sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"seatNumber" ascending:YES selector:@selector(localizedStandardCompare:)]]];
output
{
"seats": [{
"seatNumber": "1"
}, {
"seatNumber": "2"
}, {
"seatNumber": "10"
}]
}
documentation: https://developer.apple.com/documentation/foundation/nsstring/1409742-localizedstandardcompare
Upvotes: 0
Reputation: 11
All the above methods need good knowledge of basics to implement; but for the newbies I suggest the simplest way – to use the native block method
NSArray* sortedArr =[fetchResults sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
int aValue = [[a valueForKey:@"subgroupId"] intValue];
int bValue = [[b valueForKey:@"subgroupId"] intValue];
return aValue > bValue;
}];
Upvotes: 0
Reputation: 9185
NSMutableArray *list = [NSMutableArray arrayWithObjects:@"11",@"2",@"3",@"1", nil];
[list sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSInteger firstInteger = [obj1 integerValue];
NSInteger secondInteger = [obj2 integerValue];
if( firstInteger > secondInteger) return NSOrderedDescending;
if( firstInteger == secondInteger) return NSOrderedSame;
return NSOrderedAscending; // edited
}];
No guarantees about performance
Upvotes: 7
Reputation: 214
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort.intValue" ascending:YES];
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];
Sort based on the value of the integer.
Upvotes: 16
Reputation: 64002
You need your strings to be compared with the NSNumericSearch
option:
NSNumericSearch
Numbers within strings are compared using numeric value, that is,Name2.txt
<Name7.txt
<Name25.txt
.
which requires the compare:options:
method to be called for the comparison.
In order to do that, your sort descriptor can use an NSComparator
Block:
[NSSortDescriptor sortDescriptorWithKey:@"self"
ascending:YES
comparator:^(NSString * string1, NSString * string2){
return [string1 compare:string2
options:NSNumericSearch];
}];
Or, indeed, you can skip the sort descriptor and simply sort the array directly, using the same Block:
[unsortedList sortedArrayUsingComparator:^NSComparisonResult (NSString * string1, NSString * string2){
return [string1 compare:string2
options:NSNumericSearch];
}];
Upvotes: 11
Reputation: 3463
[list sortUsingSelector:@selector(localizedStandardCompare:)];
will sort the list in a "human" way (so "11" will come last, not between "1" and "2"). But if you really do want to treat these strings as numbers, you should make them number first!
Upvotes: 39
Reputation: 15722
You can do this by implementing a custom comparator block when creating your NSSortDescriptor
:
NSSortDescriptor *aSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sort" ascending:YES comparator:^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([obj1 integerValue] < [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];
See Apple documentation here
Upvotes: 44