Sort a complex NSarray - objective-c

I have an NSArray *userInputs, this array contains custom objects "UserInput".
#interface UserInput :NSObject {
NSString *page_id;
#end
Each userInput ( instance of UserInput) belog to BookPage.
#interface BookPage: NSobject {
NSString *pagePrefix; ( exemple : pagePrefix = #"K1")
#end
From each userInput i know to witch BookPage it's belong like this :
BookPage *bookPage = [self.book pageWithID:userInput.page_id];
how i can sort an array of userInputs ( instances of UserInputs) with the pagePrefix Key. Thanks for your answers ?

You can sort the array of custom object like this:
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"pagePrefix" ascending:YES];
[userInputs sortUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]];

You can sort array like(considering your array contains strings) -
sortedArray = [userInput sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];

I think there is a book property in the middle?
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"book.pagePrefix" ascending:YES];
[userInputs sortUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]];

Related

How to fetch data of NSString from array of structure hold by NSMutableArray in objective c?

I have one NSMutableArray tempArray = \[NSMutableArray array\]; which contains an array of structured objects with multiple data: brand_package_id , slide_master_id etc....
I want to sort out the tempArray according to slide_master_id's.
Please see given image and help me to sort this problem.
Try using NSSortDescriptor:
NSSortDescriptor *slideDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"slide_master_id" ascending:YES];
NSArray *sortDescriptors = #[slideDescriptor];
NSArray *sortedArray = [tempArray sortedArrayUsingDescriptors:sortDescriptors];

Sort array by comparing string value in Objective C

I have an array of custom objects. Objects contain status : paid or unpaid.
I want to sort array like :
On first click, sort array to display paid records first and then unpaid records.
On second click, sort array to show unpaid records and then paid records.
Any help ?
you can try below like statement:
NSSortDescriptor *Sorter = [NSSortDescriptor sortDescriptorWithKey:#"yourfield" ascending:YES selector:#selector(caseInsensitiveCompare:)];
[yourArray sortUsingDescriptors:[NSArray arrayWithObject:Sorter]];
You can do as :
- (IBAction)sort:(id)sender {
static BOOL isPaidFirst=YES;
NSSortDescriptor *Sorter = [NSSortDescriptor sortDescriptorWithKey:#"isPaid"
ascending:!isPaidFirst
selector:#selector(compare:)];
[self.array sortUsingDescriptors:[NSArray arrayWithObject:Sorter]];
isPaidFirst=!isPaidFirst;
for (MyObject *obj in self.array) {
NSLog(#"-->%#, %ld, %d",obj.courseName, obj.totalFee, obj.isPaid);
}
NSLog(#"------------------");
}
Here MyObject is as :
#interface MyObject : NSObject
#property(strong)NSString *courseName;
#property NSInteger totalFee;
#property BOOL isPaid;
#end

Sort NSMutableArray Of multiple Objects without keys

I have a NSMutableArray of objects, below is the struct:
//object at index i
locations {
NSString* address;
NSString* state;
NSNumber* distance;
}
I have 10000 object like the above structure in the NSMutableArray.
How do order this array so that the locations are in order by the NSNumber distance?
I tried this:
lowToHigh = [NSSortDescriptor sortDescriptorWithKey:#"distance" ascending:YES];
[locationArray sortUsingDescriptors:[NSArray arrayWithObject:lowToHigh]];
is using the sortDescriptorWithKey:#"distance" wrong? since distance isn't actually a key, it NSNumber* distance.
edit in my header #property (strong, nonatomic)NSNumber* _distance; and then #synthesize _distance = distance; in my methods file but this is in locationObjects.* object class. Then I import this in my current class I am doing this sorting. Is that an issue?
How I import is locationObjects* locObj = [[locationObjects alloc] init];
This is what I use:
NSSortDescriptor *lowToHigh = [[NSSortDescriptor alloc] initWithKey:#"distance"
ascending:YES];
NSArray *mySortDescriptors = [NSArray arrayWithObject:lowToHigh];
NSArray *sortedArray = [locationArray sortedArrayUsingDescriptors:mySortDescriptors];

sorting NSmutable array contains object according to double value

I want to order NSMutableArray contain objects according to two of object property one of them has double type second has NSString ?
I tried to use this method but I got exception :
NSString * LASTNAME = #"lastName";
NSString * GRADE = #"grade";
NSSortDescriptor *lastDescriptor =
[[NSSortDescriptor alloc]
initWithKey:LASTNAME
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *firstDescriptor =
[[NSSortDescriptor alloc]
initWithKey:GRADE
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)]];
NSArray * descriptors =
[NSArray arrayWithObjects:lastDescriptor, firstDescriptor, nil];
NSArray * sortedArray =
[students sortedArrayUsingDescriptors:descriptors];
#interface Student : NSObject
{
NSString * firstName;
NSString * lastName;
double grade;
}
NSNumber doesn't respond to localizedCaseInsensitiveCompare:. You want just plain compare: for the number.
Numbers don't have a case, try using compare: for GRADE
After Edit: You didn't say what error you got. Did the code you posted even compile? You have a typo in your firstDescriptor -- one too many "]" at the end of the method. You probably fixed that when you took out the compare: (which shouldn't have fixed anything).
Remove localizedCaseInsensitiveCompare
NSSortDescriptor *firstDescriptor =
[[NSSortDescriptor alloc]
initWithKey:GRADE
ascending:YES]];

Sort NSArray of custom objects by their NSDate properties

I am attempting to sort an NSArray that is populated with custom objects. Each object has a property startDateTime that is of type NSDate.
The following code results in an array, sortedEventArray, populated but not sorted. Am I going about this the completely wrong way or am I just missing something small?
NSSortDescriptor *dateDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"startDateTime"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [nodeEventArray sortedArrayUsingDescriptors:sortDescriptors];
Are you sure that the startDateTime instance variables of the node events are non-nil?
If you don't have one already, you might add a (custom) -description method to your node event objects that does something like this:
- (NSString *)description {
return [NSString stringWithFormat:#"%# - %#",
[super description], startDateTime]];
}
Then in your sorting code log the array before and after:
NSLog(#"nodeEventArray == %#", nodeEventArray);
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
sortDescriptorWithKey:#"startDateTime"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [nodeEventArray
sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"sortedEventArray == %#", sortedEventArray);
If the startDateTime's are all nil, then the before and after arrays will have the same order (since the sorting operation will equate to sending all the -compare: messages to nil, which basically does nothing).
Did you try by specifying the NSDate comparator?
Eg:
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
sortDescriptorWithKey:#"startDateTime"
ascending:YES
selector:#selector(compare:)];
This should enforce the usage of the correct comparator of the NSDate class.
Ok, I know this is a little late, but this is how I would do it:
NSArray *sortedEventArray = [events sortedArrayUsingComparator:^NSComparisonResult(Event *event1, Event *event2) {
return [event1.startDateTime compare:event2.startDateTime];
}];
Obviously, replace Event with the class of your custom object. The advantage of this approach is that you are protected against future refactoring. If you were to refactor and rename the startDateTime property to something else, Xcode probably would not change the string you're passing into the sort descriptor. Suddenly, your sorting code would break/do nothing.
You can achieve like this,
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"anyDateField" ascending:YES];
NSMutableArray *arr = [[array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy];
You can achieve this like this,
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:FALSE];
[self.Array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];