Sort NSArray with multiple NSDictonaries in it [duplicate] - iphone

This question already has answers here:
Sorting NSArray of dictionaries by value of a key in the dictionaries
(11 answers)
Closed 9 years ago.
I need to sort the given "document" array with "lastname". Here is the sample json
document [
{
id:"100"
person :{
name : {
firstname : "xyz",
lastname : "oops"
},
photourl: "photo-url"
}
},
{
id:"200"
person :{
name : {
firstname : "xyz",
lastname : "oops"
},
photourl: "photo-url"
}
}]
it has an dict "name" inside one more dict "person" and we need to sort with lastname first n then with lastname

NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"lastname " ascending:YES] ;
NSArray *sortedArray = [NSArray arrayWithObject:lastNameDescriptor];
sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors];
for more clear description and code check this link, its very easy and perfect, Cheers :)

Use the below given logic
for (NSMutableDictionary *document in documents) {
NSString *lastName = [[document valueForKey:#"person"] valueForKey:#"lastname"];
[documents setObject:lastName forKey:#"lastnameDescriptor"];
}
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"lastnameDescriptor" ascending:YES];
NSMutableArray *sortedNames = [documents sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
for (NSMutableDictionary *document in sortedNames) {
[document removeObjectForKey:#"lastnameDescriptor"];
}

The other answers are close but either needlessly complicated or a little off.
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"person.lastName" ascending:YES];
sortedArray = [document sortedArrayUSingDescriptors:#[descriptor]];
(The selector says "key," but if you read the docs, it's actually a keypath, so this will work as expected.)

Lots of almost right answers but none that consider that 'name' is itself a nested dictionary in your document. So I think what you want is:
NSSortDescriptor *lastNameDescriptor = [NSSortDescriptor sortDescriptorWithkey:#"person.name.lastname" ascending:YES];
NSSortDescriptor *firstNameDescriptor = [NSSorteDescriptor sortDescriptorWithKey:#"person.name.firstname" ascending:YES];
NSArray *sortedArray = [document sortedArrayUsingDescriptors:#[lastNameDescriptor, firstNameDescriptor]];

So assuming you put your JSON into an array called "people":
NSArray *people = myArrayFromJSON;
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"person" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
NSString *lastName1 = [obj1 valueForKey:#"lastname"];
NSString *lastname2 = [obj2 valueForKey:#"lastname"];
return [lastName1 compare:lastname2];
}];
NSArray *sortedArray = [people sortedArrayUsingDescriptors:#[sortDescriptor]];
That'll do it.

Related

Does NSSortDescriptor can sort array with DateTime type?

Here is my code:
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"inspectionDateTime"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
sortedArray = [listAllProject sortedArrayUsingDescriptors:sortDescriptors];
[sortedArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
UDS_ProjectField *projectField1 = obj1;
UDS_ProjectField *projectField2 = obj2;
return [projectField1.inspectionDateTime compare:projectField2.inspectionDateTime];
return YES;
}];
I use this to sort an array of a table in database which has field name "inspectionDateTime"
type DATETIME, but the result is not correct.
This is the result
15/2/12
15/1/12
12/3/12
but expecting result is
12/3/12
15/2/12
15/1/12
So the question is NSSortDescriptor can sort DateTime type, if not please show me another way
NSSortDescriptor can be used to date sorting, I used following code and it is working for me:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey::#"inspectionDateTime"
ascending:YES selector:#selector(compare:)];
[listAllProject sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
try this
NSArray *sortedArray = [listAllProject sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
UDS_ProjectField *projectField1 = obj1;
UDS_ProjectField *projectField2 = obj2;
return [projectField1.inspectionDateTime compare:projectField2.inspectionDateTime];
return YES;
}];
For more you can read docs here

How to sort a NSMutableArray using NSSortDescriptor?

I'm parsing data from JSON webservice and then using the following code to sort the data by price, date, discount etc.
here's the code I'm using to sort the data:
-(void)priceSort:(id)sender {
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey: #"price" ascending: YES];
NSMutableArray *sortedArray = (NSMutableArray *)[self.displayItems
sortedArrayUsingDescriptors: [NSArray arrayWithObject:sortDescriptor]];
[self setDisplayItems:sortedArray];
[self.tableView reloadData];
}
this works fine when I'm trying to sort by price, however when I want to sort by number of reviews I can't seem to get the code right:
for price I use:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey: #"price" ascending: YES];
but for reviews I want to get the "n" value. see how it's nested in the output (of the display Items mutableArray below:
"old_price" = 24;
price = "9.9";
reviews = {
**n = 11;**
val = 70;
};
"sold_count" = 101;
thanks for any help on this :)
To sort by the number of reviews n, your sort descriptor would be:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey: #"reviews.n" ascending: YES];

Sort an array using array index

I am stuck here......
I have two arrays Arr_title and Arr_distance
I get sorted Arr_distance using this method
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES]autorelease];
sortedFloats = [appDel.Arr_distance sortedArrayUsingDescriptors:
[NSArray arrayWithObject:sortDescriptor]];
but problem is that i want to sort Arr_title according to index of sortedFloats array...
thx in advance for help me..........
Try this,
NSDictionary *dict = [NSDictionary dictionaryWithObjects:Arr_title forKeys:Arr_distance];
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES] autorelease];
sortedFloats = [appDel.Arr_distance sortedArrayUsingDescriptors:
[NSArray arrayWithObject:sortDescriptor]];
NSMutableArray *sortedTitles = [NSMutableArray array];
for (NSString *key in sortedFloats) {//or just use sortedTitles = [dict objectsForKeys:sortedFloats notFoundMarker:[NSNull null]];
[sortedTitles addObject:[dict valueForKey:key]];
}
NSLog(#"%#",sortedValues);
sortedTitles should give you the array sorted in the same order as sortedFloats.
hey instead of taking two different array take 1 dictionary with key title,distance save that dictionary in array then sort that array So you have got combination together so there is no any problem due to mapping in any sort(by title & by distance).
if i understand your question right , you can use NSDictionary for the same task
NSMutableArray *array = [NSMutableArray arrayWithArray:#[ #{#"title" : #"City1",#"dist" : #5},
# {#"title" : #"City2",#"dist" : #2.3 },
#{#"title" : #"City3",#"dist" : #11.0 },
#{#"title" : #"City4",#"dist" : #1.0},
#{#"title" : #"City5",#"dist" : #.5},
#{#"title" : #"City6",#"dist" : #13 }]];
NSLog(#"dict<%#>",array);
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"dist" ascending:YES];
NSArray *sortarray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
NSLog(#"sort array = <%#>",sortarray);
I got the solution see following code.........
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES]autorelease];
sortedFloats = [appDel.Arr_distance sortedArrayUsingDescriptors:
[NSArray arrayWithObject:sortDescriptor]];
NSLog(#" Sorted Array : %#", sortedFloats);
NSDictionary *dictTitle = [NSDictionary dictionaryWithObjects:Arr_title forKeys:appDel.Arr_distance];
// Sort the second array based on the sorted first array
sortedTitle = [dictTitle objectsForKeys:sortedFloats notFoundMarker:[NSNull null]];
NSLog(#" Sorted Title : %#",sortedTitle);
// Put the two arrays into a dictionary as keys and values
NSDictionary *dictAddress = [NSDictionary dictionaryWithObjects:Arr_address forKeys:appDel.Arr_distance];
// Sort the second array based on the sorted first array
sortedAddress = [dictAddress objectsForKeys:sortedFloats notFoundMarker:[NSNull null]];
NSLog(#" Sorted Address : %#",sortedAddress);
Dont forgot to retain your arrays if use in another method ....

Sort array of dictionary objects

the problem im having is that i cant sort an NSMutableArray of NSMutableDictionary Objects, I want to sort the objects by rating, the rating is a NSNumber, what am i missing?
My current code that sums all the ratings from "arrayMealRating" and sorts the resulting array:
[arrayMealRating addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
[eachObject objectForKey:#"Airline"], #"Airline"
,[eachObject objectForKey:#"setMealRating"], #"setMealRating"
, nil]];
}
NSArray *airlineNames = [arrayMealRating valueForKeyPath:#"#distinctUnionOfObjects.Airline"];
// Loop through all the airlines
for (NSString *airline in airlineNames) {
// Get an array of all the dictionaries for the current airline
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(Airline == %#)", airline];
NSArray *airlineMealRating = [arrayMealRating filteredArrayUsingPredicate:predicate];
// Get the sum of all the ratings using KVC #sum collection operator
NSNumber *rating = [airlineMealRating valueForKeyPath:#"#sum.setMealRating"];
//NSLog(#"%#: %#", airline, rating);
[sortedMealArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
airline, #"Airline"
,[rating stringValue], #"setMealRating"
, nil]];
}
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"setMealRating" ascending:YES];
[sortedMealArray sortedArrayUsingDescriptors:[NSMutableArray arrayWithObjects:descriptor,nil]];
auxMealRating = [sortedMealArray copy];
Any doubt, please dont down vote, just ask and i will edit the question.
Best Regards and sorry for my poor english.
This should do what you want:
NSArray *sortedArray = [arrayMealRating sortedArrayUsingComparator:^(id obj1, id obj2) {
NSNumber *rating1 = [(NSDictionary *)obj1 objectForKey:#"setMealRating"];
NSNumber *rating2 = [(NSDictionary *)obj2 objectForKey:#"setMealRating"];
return [rating1 compare:rating2];
}];

iPhone - Sorting NSArray based on available data in dictionary

I'm having NSDictinary objects array.
Each dictionary object has keys "display_name", "first_name" and "last_name".
Some dict objects have only display_name and some will not have.
Some dict objects have only first_name and some will not have.
Some dict objects have only last_name and some will not have.
I'm using this array to show the list in table view. What I am looking for is to sort the dict with following preference:
1. If display name is available, use that.
2. If display name is not available and first name is available, use that.
3. else last name.
How can I sort the array using above preference. I want to use NSPredicate the app has to work on older iOS as well....
I tried different combinations of NSPredicate as following, but I didn't succeeed:
NSSortDescriptor* firstNameDescriptor;
NSSortDescriptor* lastNameDescriptor;
NSSortDescriptor* displayNameDescriptor;
displayNameDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"display_name" ascending:YES];
lastNameDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"last_name" ascending:YES];
firstNameDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"first_name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:firstNameDescriptor, lastNameDescriptor,nil];
self.contactsArray = (NSMutableArray*)[tempArray sortedArrayUsingDescriptors:sortDescriptors];
Can some one guide me in right way to achieve it?
you can use :
sortedArrayUsingFunction:context:
and implement the rules you just listed in your own custom sorting function
What I did is that during sorting, I added another key to the dictionary "final_name" and the value is set according to my preference of names to display and just sorted the array with "final_name".
NSArray* tempArray = [jsonData objectForKey:#"contacts"];
for (NSDictionary* conDict in tempArray)
{
NSString* fName = [conDict objectForKey:#"first_name"];
NSString* lName = [conDict objectForKey:#"last_name"];
NSString* dName = [conDict objectForKey:#"display_name"];
NSString* finalName = #"<<No Name>>";
if (dName && ![dName isEqual:[NSNull null]]) {
finalName = dName;
}
else if (fName && ![fName isEqual:[NSNull null]] && lName && ![lName isEqual:[NSNull null]])
{
finalName = [NSString stringWithFormat:#"%# %#",fName,lName];
}
else if (fName && ![fName isEqual:[NSNull null]])
{
finalName = fName;
}
else if (lName && ![lName isEqual:[NSNull null]]) {
finalName = lName;
}
[conDict setValue:finalName forKey:#"final_name"];
}
if ([tempArray count])
{
NSSortDescriptor* finalSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"final_name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:finalSortDescriptor,nil];
self.contactsArray = [[NSArray alloc] initWithArray:[tempArray sortedArrayUsingDescriptors:sortDescriptors]];
}