I have an array of NSDictionnary and I would like to sort them by an int value (the key is named "age").
For exemple :
Dic1 : age = 30, sex = male;
Dic2 : age = 24, sex = male;
Array : Dic1, Dic2;
Now with a compare method I would lik to have :
Array : Dic2, Dic1;
I tried lots of things but doesn't work. I as using NSSortDescriptor but it's only available since iOS 4.0 :(
Have you got a solution ?
Thanks !
EDIT :
I wrote a compare method on NSDictionary category :
- (NSComparisonResult)compareGood:(NSDictionary *)otherObject
{
return [[self objectForKey:#"age"] compare:[otherObject objectForKey:#"age"]];
}
But I have this crash error : Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSCFNumber compare:]: nil argument'
The documentation for NSSortDescriptor says:
Available in iOS 2.0 and later.
Likewise for the NSMutableArray method -sortUsingDescriptors:. You should be able to do this:
NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:#"age"
ascending:YES]
autorelease];
[myArray sortUsingDescriptors:[NSArray arrayWithObject:descriptor];
or, if myArray isn't mutable, do this for the second line:
NSArray *sortedArray = [myArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
Related
I fetch Realm objects named "DictObj" by list of property "index" like this:
NSArray *listIDs = #[#1000,#0,#100,#4];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"index IN %#",listIDs];
self.fetchedResults = [DictObj objectsInRealm:realm withPredicate:predicate];
I simply fetch results but it auto order by primary key "index", I want keep it order by "listIDs". So I create sortDescriptor and try custom sort it like below, but it crash with error: "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSSortDescriptor property]: unrecognized selector sent to instance 0x"
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"index" ascending:NO comparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSNumber *num1 = [NSNumber numberWithInteger:(NSInteger)obj1];
NSNumber *num2 = [NSNumber numberWithInteger:(NSInteger)obj2];
NSInteger listIndex1 = [listIDs indexOfObject:num1];
NSInteger listIndex2 = [listIDs indexOfObject:num2];
return listIndex1 < listIndex2;
}];
self.fetchedResults = [[DictObj objectsInRealm:realm withPredicate:predicate] sortedResultsUsingDescriptors:#[sortDescriptor]];
//Model
#interface DictObj : RLMObject
#property NSInteger index;
#property NSString *name;
#end
How to customize sort the result order by a list in Realm?
-[RLMResults sortedResultsUsingDescriptors:] takes an NSArray<RLMSortDescriptor *>. In your code you're passing an NSArray<NSSortDescriptor *>. RLMSortDescriptor and NSSortDescriptor are different classes with different interfaces, hence the exception you're seeing.
At present RLMResults can only be directly sorted by property value. In order to sort on computed orderings like you're after you'll need to populate an NSArray with the contents of the RLMResults, then sort on that. Adding support for this on RLMResults is being tracked in issue #1265 on Realm's GitHub repository.
The following method:
- (NSMutableArray*) timeSortedBegins {
NSMutableArray* begins = [self.spans valueForKey: #"begin"];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey: #"cycleOffsetObject" ascending: YES];
[begins sortUsingDescriptors: #[sort]];
return begins;
}
throws this runtime exception:
2014-03-21 14:41:32.482 myValve[1741:60b] -[__NSArrayI sortUsingDescriptors:]: unrecognized selector sent to instance 0x16d7bc20
2014-03-21 14:41:32.484 myValve[1741:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI sortUsingDescriptors:]: unrecognized selector sent to instance 0x16d7bc20'
I have used breakpoints to convince myself that the begins array is indeed full of (two in this case) WEAnchor* objects. And that object implements the following two methods:
- (NSTimeInterval) cycleOffset {
return self.offset + (self.datum ? self.datum.cycleOffset : 0.0);
}
- (NSNumber*) cycleOffsetObject {
return [NSNumber numberWithDouble: self.cycleOffset];
}
To be honest, I only added the cycleOffsetObject wrapper method, because I thought maybe it couldn't work with non object values, I was using initWithKey: #"cycleOffset" before that. I have not declared these in the header file as a property, they're just accessor methods, not state. Is that the problem? If it is, how do you sort by the return value of a given selector? Or is it something head smackingly obvious that I'm just missing?
As #dtrotzjr says, it sounds like your array is an immutable, not a mutable array.
You can either use mutableCopy to create a mutable copy and then sort that copy, or use the NSArray method sortedArrayUsingDescriptors: (which operates on an immutable array, and returns a sorted version of the contents as a second immutable array.)
To use mutableCopy, your code might look like this:
- (NSMutableArray*) timeSortedBegins {
NSMutableArray* begins = [[self.spans valueForKey: #"begin"] mutableCopy];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey: #"cycleOffsetObject" ascending: YES];
[begins sortUsingDescriptors: #[sort]];
return begins;
}
Check that [self.spans valueForKey: #"begin"] is actually an NSMutableArray before casting it. The error message indicates that the pointer is actually an NSArray
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFConstantString 0xa2f4> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.'
agesArray=[NSMutableArray array];
sortDescriptor *a=[[sortDescriptor alloc]init];
a.name=#"SAS";
a.lastname=#"kumar";
[agesArray addObject:a.name];
sortDescriptor *a1=[[sortDescriptor alloc]init];
a1.name=#"DAMAN";
[agesArray addObject:a1.name];
sortDescriptor *a11=[[sortDescriptor alloc]init];
a11.name=#"AKSHAY";
[agesArray addObject:a11.name];
NSSortDescriptor *sortDesc = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES selector:#selector(compare:)];
[agesArray sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
Your agesArray contains NSString objects.
[agesArray addObject:a.name]; //see you are adding string here
NSString class does not contain a property called name. So it is crashing.
Probably you may want to do something like
[agesArray addObject:a];
Side note : Give meaningful name to objects/Methods or whatever. Objective C demand it. Don`t use a,a1,a11
I created an array of objects, and one of the properties of the object is "rank". I want to sort the array by the rank value of each object in it.
It throws the following error:
-[NSSortDescriptor count]: unrecognized selector sent to instance 0x10a0537d0
Here's my method call on the array of objects:
[_objects sortUsingDescriptors:[NSSortDescriptor sortDescriptorWithKey:#"rank" ascending:YES selector:#selector(compare:)]];
And here's the relevant code from the class that the objects in the array belong to:
#synthesize rank;
- (void)initWithRank:(int)rankNum Name:(NSString*)nameString URL:(NSString*)urlString
{
self.rank = [NSNumber numberWithInt:rankNum];
self.name = nameString;
self.url = urlString;
}
As you can see, "rank" is an NSNumber, and the NSNumber class has a method called "compare:" that's supposed to compare NSNumbers by their values, so I don't understand why it's telling me the selector is unrecognized. Thanks in advance for any help.
sortUsingDescriptors: expects an NSArray of sort descriptors as its first argument:
[_objects sortUsingDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:#"rank" ascending:YES selector:#selector(compare:)]]];
Or a bit longer:
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"rank" ascending:YES selector:#selector(compare:)];
[_objects sortUsingDescriptors:#[descriptor]];
I am trying to sort an NSMutableArray with the following structure:
(
{
Code = "390954-150";
Size = "35";
},
{
Code = 790540MSO;
Size = "30";
}
)
I am trying to sort basing on the Code value, the NSMutableArray is called arrayProduct:
//Sort array by Code
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"Code" ascending:YES];
[arrayProduct sortUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]];
//
However the above code throws the following exception:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object'
Your arrayProduct looks to be NSArray.
Try converting it into NSMutableArray and :
NSMutableArray *mutableProducts = [NSMutableArray arrayWithArray:arrayProduct];
[mutableProducts sortUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]];