Objective C custom array sorting algorithm error - objective-c

I am sorting an array of custom winery objects by a name attribute.
wineryNames = [NSMutableArray arrayWithArray:[wineryNames sortedArrayUsingComparator:^(Winery *a, Winery *b){
return [a.getName compare:b.getName options:NSCaseInsensitiveSearch];
}]];
I am receiving an error on the return line and the log says 'unrecognized selector'. I have no idea why this isn't working.

I think this will do the job:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES
selector:#selector(caseInsensitiveCompare:)];
NSArray *sortedArray = [wineryNames sortedArrayUsingDescriptors:#[sortDescriptor]];
More info Here!

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];

Ios error while sorting an NSArray

When I try to sort an array, I got an exception like below:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key levels.'
To sort the arrays I use the following lines:
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"levels" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject: descriptor];
NSArray *reversedLevelIdArray = [levelsDictionary.allKeys sortedArrayUsingDescriptors:descriptors];
The levelsDictionary.allKeys contains the values like below:
( level2, level1 )
What is wrong with my code?
Using Sort Descriptor...
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject: descriptor];
NSArray *reversedLevelIdArray = [levelsDictionary.allKeys sortedArrayUsingDescriptors:descriptors];
NSLog(#"%#", reversedLevelIdArray);
You can use #selector to sort an array...
NSArray *resultArray = [levelsDictionary.allKeys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
Using Comparator....
NSArray *resultArray = [levelsDictionary.allKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return obj2 > obj1;
}];
Just use the following codes to sort the array, instead of all of your other line of codes..
NSArray *reversedIdArray = [levelsDictionary.allKeys sortedArrayUsingDescriptors:#selector(caseInsensitiveCompare:)];
You're sorting strings and they are ahving no property or method named levels. You should sort the values instead, like:
[levelsDictionary.allKeys sortedArrayUsingSelector:#selector(compare:)];
I have checked you code, you are sorting the data and accessing the wrong key name of dictionary.
As you said that your levelDictionary contains the keys name as "level2", "level1", etc....
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"levels" ascending:YES];
In this code you have used the key name as "levels" is wrong, because I think your dictionary "levelsDictionary" does not contains any key name as "levels".
Please try to use the proper key name and your error will resolve.

Sort descriptor not working on nsdate objects in NSArray.

An array contains NSDate objects, how to sort these using sort descriptor ? I am trying the code below:
NSSortDescriptor * dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"Date" ascending:YES];
NSArray * sortedArray = [allDates addObjectsFromArray:[allDates sortedArrayUsingDescriptors:#[dateSortDescriptor]]];
NSDate conforms to the compare: method and ascending is the default order
NSArray *sortedArray = [allDates sortedArrayUsingSelector:#selector(compare:)];
#Avt, answered this question I don't know why he removed it.
NSSortDescriptor * dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"timeIntervalSince1970" ascending:YES];
NSArray * sortedArray = [allDates addObjectsFromArray:[allDates sortedArrayUsingDescriptors:#[dateSortDescriptor]]];

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]];

How to sort an array which contains Dictionaries?

I have an array which contains dictionaries in it; so how can I sort the array according to dictionary key values?
If every element in the array is a dictionary containing a certain key, you can sort the array using a sort descriptor. For instance, if every element is a dictionary containing a key called "name":
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:sortDescriptors];
The other way to achieve this would be using sortedArrayUsingComparator: method
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 valueForKey:#"value"] compare:[obj2 valueForKey:#"value"]];
}];
why don't you use a sorted dictionary where the property of sorted elements comes already with the data structure?
Please do check it out here
Hope this helps.
The above shared answer by Bavarious helped me.Just want to add one more thing.If you want to sort a mutable array use something like the below code
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSMutableArray *sortedArray = [[NSMutableArray sortedArrayUsingDescriptors:sortDescriptors]mutableCopy];
let arrDescriptor = NSSortDescriptor(key: "order", ascending: true)
let sortDescriptors: NSArray = [arrDescriptor]
let sortedArray = instancesubArray.sortedArray(using: sortDescriptors as [AnyObject] as [AnyObject] as! [NSSortDescriptor])
print(sortedArray)