Sorting Array Alphabetically for section tableview - ios

How to sort an array alphabetically to return all objects data instead of single name? And how to set these data in section tableview? Number of rows in section method - how it works, please help me.

You can sort your array with a sort descriptor. in the sort descriptor you set the attrib of the array elements which shall be used for sorting:
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"yourAttribInArrayElememts" ascending:YES];
NSArray *sortedArray = [yourArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];

Create this method inside your Object class
-(NSComparisonResult) compareWithObjectClass: (YourObjectClass *) otherObject
{
return [self.name compare:otherObject.name]
}
Then, in your viewcontroller, you can call sortUsingComparator method to order your array of objects
//Order items Array
[self.itemsArray sortUsingComparator:^NSComparisonResult(YourObjectClass *obj1, YourObjectClass *obj2){
return [obj1compareWithObjectClass:obj2];
}];

Related

Objective-C, Sorting an NSMultable array of type class, alphabetically?

I'm trying to sort a property on a type of a mutable array.
However I've only managed to sort a NSString array.
NSMutableArray<DBFILESFileMetadata*> *tmpArray = [[NSMutableArray alloc]init];
for (DBFILESMetadata *entry in entries)
{
//conditions
[tmpArray addObject:fileMetadata];
}
Here's the type / class
https://github.com/dropbox/dropbox-sdk-obj-c/blob/4c99bdf726cf9724adfddc19e71a87a6012eddeb/Source/ObjectiveDropboxOfficial/Shared/Generated/ApiObjects/Files/Headers/DBFILESMetadata.h
I've tried
[yourArray sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
and
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
[yourArray sortUsingDescriptors:[NSArray arrayWithObject:sort]];
The property is called name.
I've seen answer like this How can I sort an NSMutableArray alphabetically? but I can't seem to get this to work for my scenario.
In order to sort using sortUsingSelector you need to implement your compare method in the objects that you are trying to compare. (So your DBFILESMetadata class would need a compare method - localizedCaseInsensitiveCompare in the code above.)
You should be able too use a sort descriptor as you show in your second attempt. What happens when you do that?
A third way to do it is to use the NSMutableArray sortUsingComparator and write an NSComparator block that compares the 2 objects.
I'm out of practice with Objective-C but a quick Google search found an example, which I adapted to your specific problem:
[entries sortUsingComparator:
^NSComparisonResult(DBFILESMetadata *obj1, DBFILESMetadata *obj2)
{
return [obj1.name localizedCaseInsensitiveCompare: obj2.name];
}];
That should work, although as I say I'm out of practice in Objective-C, and its block syntax is pretty awkward and counter-intutive.

Sort Database object

I have a UITableView each cell shows unique menu item I want items to be sort in my list but those menu items are not coming from an array but from a db object
Example:
cellForRowAtIndexPath{
Menus_Items *menuItem = [menuCategory.hasMenuItems.allObjects objectAtIndex:indexPath.row];
lblMenuItemName.text = menuItem.name;
}
How can I sort menu items ? I could have done it if it was an array i.e.
NSSortDescriptor *orderSort = [[NSSortDescriptor alloc] initWithKey:#"order" ascending:NO];
// String are alphabetized in ascending order
NSSortDescriptor *strNameSort = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
// Combine the two
NSArray *sortDescriptors = #[orderSort, strNameSort];
arrCategories = [DatabaseHelper getAllData:#"Menus_cat" offset:0 predicate:[NSPredicate predicateWithFormat:#"ofOutlet == %#",outletsObject] sortDescriptor:nil];
// sortedArrayUsingDescriptor is the method use to sort an array which is having multiple parameters in sort descriptor
arrCategories = [arrCategories sortedArrayUsingDescriptors:sortDescriptors];
Help please. Thanks in advance
menuCategory.hasMenuItems.allObjects is an array so you can sort it to get the appropriate item. You could sort it each time or keep a sorted cache of the content. Neither of these options is ideal.
Really, you want to use a fetch request with a sort descriptor, ideally managed by a fetch request controller. Usually you would do that by using the relationship 'backwards'. So, you create the fetch and set the predicate to XXX = %#, where XXX is the relationship name and the supplied parameter is menuCategory.
This is assuming the relationship is 1:many, if it's many:many you will need a different predicate form.

Sorting an NSArray and case precedence

I have a list of managed objects stored in core data. I use these objects to populate a tableview controller that is sectioned according to alphabetical order. The data in these objects is obtained via web service, so I have no control over their case (which really doesn't make much difference in this case).
Most of the data is returned in all caps. I've noticed that, on the rare occasions where the case is NOT all caps, those items do not fall into alphabetic order. In the following code sample, stationIndex is an array of sorted first letters:
for(NSString *character in stationIndex){
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name beginswith[c] %#", character];
// sort the list
NSArray *filteredGaugeList = [[tempGaugeList filteredArrayUsingPredicate:pred] sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [(Gauge*)a name];
NSString *second = [(Gauge*)b name];
return [first compare:second];
}];
if([filteredGaugeList count] > 0){
[[self allGauges] addObject:filteredGaugeList];
}
}
I'm aware that there is a way to ignore case when using a selector, but in my case, I'm sorting on properties of objects, so I'm assuming I need a comparator. Is there a way to handles case in this situation? Thanks!
You can sort ignoring case in a comparator as well, just use
return [first caseInsensitiveCompare:second];
Alternatively, use a sort descriptor specifying the selector and the sort key:
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES
selector:#selector(caseInsensitiveCompare:)];
NSArray *sorted = [array sortedArrayUsingDescriptors:#[sort]];
Remark: To display Core Data objects in a table view, you can also use
NSFetchedResultsController. Then you would add the predicate and the sort
descriptor to the fetch request. A fetched results controller has also methods
to group a table view into sections, and to update a table view automatically
when objects are inserted/deleted/modified.

NSSortdescriptor not mixing lists

I've got an array which should be sorted by name, but only the half of it gets sorted. I've got a list of entries which can be devided in two parts, the first part comes from a dictionary and only has the property "name", the second part comes from a core data database and got as well the property "addedByUser". both of the lists are inside the tempArray and get added into the _resultsarray, which then directly leads to the cellForRowAtIndexPath. But before, I try to sort _resultsarray by name. Now the problem occurs: first the list without the addedByUser attribute appears (sorted by name) and then the other list (with addedByUser attribute") appears, sorted by name as well. I can't get them to be mixed.
[_resultsarray addObjectsFromArray:tempArray];
// Sort the list
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
[_resultsarray sortUsingDescriptors:[NSArray arrayWithObject:sort2]];
What am I doing wrong? Thank you!
Update: I'm very sorry, I forgot to write that both tempArray and _resultsarray are mutable arrays.
Update 2: It seems like it makes a difference if the names start with an uppercase or lowercase character. My updated question is then, is there a way to sort an NSMutableArray no matter if the words start with uppercase or lowercase character?
Update 3: I found out:
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES selector:#selector(caseInsensitiveCompare:)];
You should write an NSComparoator like:
_resultsarray = [tempArray sortedArrayUsingComparator:^(id firstObject, id secondObject) {
NSString *name1 = ... ; // firstObject.name or firstObject.addedByUser
NSString *name2 = ... ; // secondObject.name or secondObject.addedByUser
return [name1 compare:name2];
}];
Try this:
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
_resultsarray = [tempArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort2]];

Best way to sort an NSArray of NSDictionary objects?

I'm struggling with trying to sort an array of dictionaries.
My dictionaries have a couple of values of interest, price, popularity etc.
Any suggestions?
Use NSSortDescriptor like this..
NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:#"interest" ascending:YES];
stories = [stories sortedArrayUsingDescriptors:#[descriptor]];
recent = [stories copy];
stories is the array you want to sort. recent is another mutable array which has sorted dictionary values. Change the #"interest" with the key value on which you have to sort.
All the best
[array sortUsingDescriptors:[NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:#"YOUR-KEY" ascending:YES], nil]];
I don't really want to break it into multiple lines. It's already simple enough for me.
You can just traverse from the parent to the required child property. For e.g.
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"parent.child.child" ascending:YES];
Update , sortUsingDescriptors is now sortedArrayUsingDescriptors
So, its like:
items = [items sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];
Write a sort function that compares the relevant fields in two dictionaries. When you have this version you can for example use NSArray#sortedArrayUsingFunction:context: to sort your array.
See NSArray Class Reference
array = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:#"YOUR-KEY" ascending:YES], nil]];
Remember assign to array

Resources