'Sorting objects in NSMutableArray with sortUsingComparator
I have the following mutable array:
NSMutableArray *persons = [[NSMutableArray alloc]initWithObjects:person1, person2, person3, nil];
where every person is an object, which contains (NSInteger) personAge and (NSString*) personName properties. Now I want to sort this array by personAge. So I tried the following:
[persons sortUsingComparator:
^NSComparisonResult(id obj1, id obj2)
{
Person *p1 = (Person*)obj1;
Person *p2 = (Person*)obj2;
return [p1.personAge compare: p2.personAge];
}];
NSLog(@"%ld", [persons componentsJoinedByString:@" "]);
But I'm getting a "Bad receiver type 'NSInteger' (aka 'long')" error message in the return line. Also I have a warning in the NSLog line: "Format specifies type 'long' but the argument has type 'NSString *'". How do I fix it?
Solution 1:[1]
Shouldn't you use something like this instead?
[persons sortUsingComparator:
^NSComparisonResult(id obj1, id obj2) {
Person *p1 = (Person*)obj1;
Person *p2 = (Person*)obj2;
if (p1.personAge > p2.personAge) {
return (NSComparisonResult)NSOrderedDescending;
}
if (p1.personAge < p2.personAge) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}
];
The thing is that you have rely on the compare method which doesn't exist on NSInteger: it is only a typedef of int. So you want to compare integer value instead and returns an NSComparisonResult value to denote the ordering of your object accordingly.
Solution 2:[2]
You're trying to call compare: on an NSInteger, which is not an object; it's a typedef for an integer type (either int or long depending on architecture).
Also, componentsJoinedByString: returns an NSString, not an integer.
Try:
[persons sortUsingComparator:
^NSComparisonResult(id obj1, id obj2)
{
Person *p1 = (Person*)obj1;
Person *p2 = (Person*)obj2;
if (p1.personAge < p2.personAge)
return NSOrderedAscending;
if (p1.personAge > p2.personAge)
return NSOrderedDescending;
return NSOrderedSame;
}];
NSLog(@"%@", [persons componentsJoinedByString:@" "]);
Solution 3:[3]
Regarding the "Bad receiver type..." error, NSInteger is a primitive data type (not an Objective-C class) so you can't call methods on it. what you want to do is the following:
if (p1.personAge > p2.personAge) {
return (NSComparisonResult)NSOrderedDescending;
}
if (p1.personAge < p2.personAge) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
The warning is due to the fact that @"%ld" is the format string for a long (as the warning says), but -componentsSeparatedByString: returns an NSString object. The correct format string for any Objective-C object is @"%@", so the line should read NSLog(@"%@", [persons componentsJoinedByString:@" "]);.
Solution 4:[4]
Like tigeguero's answer but tidier:
[people sortUsingComparator:
^NSComparisonResult(Person* p1, Person* p2){
if (p1.personAge > p2.personAge) {
return NSOrderedDescending;
}
else if (p1.personAge < p2.personAge) {
return NSOrderedAscending;
}
else{
return NSOrderedSame;
}
}
];
Solution 5:[5]
[YOURMutableArray sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Iulian Onofrei |
| Solution 2 | Wevah |
| Solution 3 | jrtc27 |
| Solution 4 | malhal |
| Solution 5 | Hiren |
