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]];
Related
I have an NSMutableArray and on every index I have another NSMutableArray but of different length like 2, 3, 4. I want to sort main array that the inside array who have bigger length come on top.
You can sort them using a descriptor:
NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:#"count" ascending:NO];
[myArray sortUsingDescriptors:#[sd]];
The above code creates one sort descriptor on the property called "count" in descending order.
//Create a sort descriptor based on count using NSSortDescriptor class as-
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"count" ascending:NO];
//& sort your main array using sort descriptor
[mainArray sortUsingDescriptors:#[sortDescriptor]];
I have name and distance fields in an array of data that I want to sort; I can sort by either one but not both together. I want the data sorted by name first, then distance, but when I use the two together, the sort is always on the first descriptor in the list, the second seems to get ignored.
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc]
initWithKey:#"NAME"
ascending:YES
selector:#selector(localizedStandardCompare:)];
NSSortDescriptor *distanceSort = [[NSSortDescriptor alloc]
initWithKey:#"DISTANCE"
ascending:YES];
sortedArray = [featureSet.features sortedArrayUsingDescriptors:#[nameSort, distanceSort]];
[super.tableView reloadData];
The behavior you're seeing definitely makes sense - "A&W #0338" comes before "A&W #0339", so there is nothing more for the distance sort to determine.
If all of your data is structured this way - a name followed by #000 - you can strip the numbers off for your sort, and then your distance sort can do its job. You can either do that at the model layer by splitting your title into two properties, a name and location number, or you can do it inside of a sort descriptor.
NSSortDescriptor *nameSort = [NSSortDescriptor sortDescriptorWithKey:#"title" ascending:YES comparator:^NSComparisonResult(NSString *str1, NSString *str2) {
NSString *title1 = [[str1 componentsSeparatedByString:#" #"] firstObject];
NSString *title2 = [[str2 componentsSeparatedByString:#" #"] firstObject];
return [title1 compare:title2];
}];
If you use this nameSort and your distanceSort, "A&W #0338", "25 km" will come after "A&W #0339"
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.
I am trying to sort an array of UserWrapper objects. The wrapper object contains the object User, and the User object contains the property UserName (that I want to sort by).
It us easy enough to sort an array of Users (source), but the added layer of UserWrapper complicates things for me. Help please!
Here is my code, which worked for a simple User array:
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"UserName"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)] ;
NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor];
NSMutableArray *contactsStartingWithKey = [nameIndexesDictionary objectForKey:aKey];
[contactsStartingWithKey sortUsingDescriptors:descriptors]; // Exception thrown here because UserName is not a property of UserWrapper, but of UserWrapper.User
The key argument of the sort descriptor can also by a key path, in your case:
[[NSSortDescriptor alloc] initWithKey:#"User.UserName"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)] ;
Although the API and documentation of NSSortDescriptor are a bit inconsistent, the "key" parameter is actually a key path. So, you can just specify #"User.UserName" as the key and your code should work.
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