the NSMutableArray I want to sort looks like this:
(
{
"title" = "Bags";
"price" = "$200";
},
{
"title" = "Watches";
"price" = "$40";
},
{
"title" = "Earrings";
"price" = "$1000";
}
)
It's an NSMutableArray which contain a collection of NSMutableArrays. I want to sort it by price first then by title.
NSSortDescriptor *sortByPrices = [[NSSortDescriptor alloc] initWithKey:#"price" ascending:YES];
NSSortDescriptor *sortByTitle = [[NSSortDescriptor alloc] initWithKey:#"title" ascending:YES];
[arrayProduct sortedArrayUsingDescriptors:[NSArray arrayWithObjects:sortByPrices,sortByTitle,nil]];
However, that didn't seems to work, how to sort a nested NSMutableArray?
Try
NSMutableArray *arrayProducts = [#[#{#"price":#"$200",#"title":#"Bags"},#{#"price":#"$40",#"title":#"Watches"},#{#"price":#"$1000",#"title":#"Earrings"}] mutableCopy];
NSSortDescriptor *priceDescriptor = [NSSortDescriptor sortDescriptorWithKey:#""
ascending:YES
comparator:^NSComparisonResult(NSDictionary *dict1, NSDictionary *dict2) {
return [dict1[#"price"] compare:dict2[#"price"] options:NSNumericSearch];
}];
NSSortDescriptor *titleDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"title" ascending:YES];
[arrayProducts sortUsingDescriptors:#[priceDescriptor,titleDescriptor]];
NSLog(#"SortedArray : %#",arrayProducts);
I suppose the error is that price is a string. As such, it isn't compared numerically, but lexicographically. Try sorting the array using a comparator block and parsing the price inside that block instead:
[array sortUsingComparator:^(id _a, id _b) {
NSDictionary *a = _a, *b = _b;
// primary key is the price
int priceA = [[a[#"price"] substringFromIndex:1] intValue];
int priceB = [[b[#"price"] substringFromIndex:1] intValue];
if (priceA < priceB)
return NSOrderedAscending;
else if (priceA > priceB)
return NSOrderedDescending;
else // if the prices are the same, sort by name
return [a[#"title"] compare:b[#"title"]];
}];
Try this
Apple doc
This well help you
Related
I have a UITableView and a UICollectionView inside. I wanted to sort this to Descend (Latest Post First). How do I want to do this?, I tried a couple of methods and all are not working.
Following are my code and responses
[Utilities serverRequest:#{#"getAnnouncement":#"a6dba37437ced2c3b07469fd6c0661f3"} completionBlock:^(id response) {
collectionViewDic[#"announcement"] = response[#"response"];
_annArray = response[#"response"];
NSLog(#"AnnouncementResponse%#",response);
// sorting to newest
/*
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc]initWithKey:#"anc_id" ascending:NO];
NSMutableArray *sortDescriptors = [NSMutableArray arrayWithObject:sortDescriptor];
[_annArray sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"Sorted - AnnouncementResponse%#",response);
*/
/*
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"anc_id" ascending:NO];
NSArray* sortedArray = [_annArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSLog(#"Sorted Array Response -%#",sortedArray);
*/
announcmentDone = YES;
if (newsDone && bulletInDone && announcmentDone && !refreshed) {
refreshed = YES;
[table reloadData];
}
} errorBlock:nil];
_annArray is actually an NSDictionary, with keys "September 2017", "August 2017" etc... The value of each key is then an array with a single NSDictionary in it as far as I can see. To get all the values you'd need something like:
NSArray *responseValues = [response[#"response"] allValues]; // An NSArray of NSArrays
NSMutableArray *dictionarys = [NSMutableArray new];
for (NSArray *dictArrays in responseValues) {
for (NSDictionary *dict in dictArrays) {
[dictionarys addObject:dict];
}
}
_annArray = dictionarys;
You should then be able to sort like you're expecting:
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"anc_id" ascending:NO];
NSArray* sortedArray = [_annArray sortedArrayUsingDescriptors:#[sortDescriptor]];
NSLog(#"Sorted Array Response -%#", sortedArray);
This is a quick, rough way of doing it though. In practise it would be far better to parse each block of JSON into an object, with type checking and sorting the objects.
I would like to sort an array using the dictionary values "Name" and "Count". It would be Name alphabetically and split the names up into two groupd based on count.
bigger than 0
Smaller than Equal 0
My current implementation looks like this however it dose not split the groups up correctly.
NSSortDescriptor *sortCountDescriptor = [[NSSortDescriptor alloc] initWithKey:#"count" ascending:NO];
NSSortDescriptor *sortNameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray * sortDescriptors = [NSArray arrayWithObjects:sortCountDescriptor, sortNameDescriptor, nil];
NSArray *sortedArray = [myArrayToSort sortedArrayUsingDescriptors:sortDescriptors];
return [sortedArray mutableCopy];
If by grouping you mean making them separate arrays then you need an NSPredicate instead of NSSortDescriptor for count key.
Try this (from what I understood the array is filled with instances of NSDictionary so I used casting to it. If that assumption is incorrect, the NSPredicate isn't hard to change to some other type or to be made more generic with KVC):
NSSortDescriptor *sortNameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
NSArray * sortDescriptors = [NSArray arrayWithObjects:sortNameDescriptor, nil];
NSArray *sortedArray = [myArrayToSort sortedArrayUsingDescriptors:#[sortNameDescriptor]];
NSPredicate *zeroOrLessPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
if ([[((NSDictionary*)evaluatedObject) objectForKey:#"count"] integerValue] <= 0) {
return YES;
}
else {
return NO;
}
}];
NSArray *zeroOrLessArray = [sortedArray filteredArrayUsingPredicate:zeroOrLessPredicate];
NSPredicate *moreThanZeroPredicate = [NSCompoundPredicate notPredicateWithSubpredicate:zeroOrLessPredicate];
NSArray *moreThanZeroArray = [sortedArray filteredArrayUsingPredicate:moreThanZeroPredicate];
I have an array with multiple dictionary like:
{
highRate = "600.49";
hotelId = 439607;
hotelRating = "2.5";
latitude = "12.97153";
longitude = "80.15096";
lowRate = "600.49";
name = "Hotel Kingss Park";
proximityDistance = "17.999475";
thumbNailUrl = "http://images.travelnow.com/hotels/7000000/6510000/6500300/6500296/6500296_3_t.jpg";
tripAdvisorRating = "4.0";
},
{
highRate = "990.0";
hotelId = 327929;
hotelRating = "2.0";
latitude = "13.06931";
longitude = "80.2706";
lowRate = "450.45";
name = "Mallika Residency";
proximityDistance = "1.6274245";
thumbNailUrl = "http://images.travelnow.com/hotels/3000000/2960000/2958400/2958303/2958303_2_t.jpg";
tripAdvisorRating = "2.5";
}
I try to sort this array using lowRate key.
NSSortDescriptor *rating_Sort = [NSSortDescriptor sortDescriptorWithKey:#"lowRate" ascending:NO];
NSArray *descriptorArray = [NSArray arrayWithObject:rating_Sort];
NSArray *sortedArray = [self.tblDisplayArray sortedArrayUsingDescriptors:descriptorArray];
here self.tblDisplayArray is my array.
But not getting proper sorted array in Result.
Why this happen?
They are all strings so it is attempting to sort them alphabetically not numerically. Try either:
NSSortDescriptor *desc = [[NSSortDescriptor alloc]initWithKey:#"doubleValue" ascending:YES];
or using NSNumbers instead of NSString... #() instead of #"".
#Rajesh is correct, not all your numbers are integers so you should be using doubleValue, I have updated the code!
Hope this helps! :)
change this
NSSortDescriptor *rating_Sort = [NSSortDescriptor sortDescriptorWithKey:#"lowRate.doubleValue" ascending:NO];
and it's working fine.
As #Georgegreen pointed they are all strings so it is attempting to sort them alphabetically not numerically.
but you should be using float or double to be precise instead of int.
NSSortDescriptor *desc = [[NSSortDescriptor alloc]initWithKey:#"doubleValue" ascending:YES];
Or just do:
NSArray *sortedArray = [[yourTempArray sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
You've array of string which is actually double value. So you sort descriptors as below.
NSSortDescriptor *aSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"sort" ascending:YES comparator:^(id obj1, id obj2) {
if ([obj1 doubleValue] < [obj2 doubleValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
sortedArray = [yourArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]];
My NSArray contains NSDictionary instances, and in the dictionaries I have orderid.
I want to make them sort in descending order. But it is not sorting.
I have tried this code
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"orderid" ascending:FALSE];
[self.orderArray sortUsingDescriptors:[self.orderArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
And this code :
[self.orderArray sortUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"orderid" ascending:NO]]];
But it didn't worked.
Here is the log
orders : (
{
orderid = 6739;
},
{
orderid = 6740;
},
{
orderid = 6745;
},
{
orderid = 6746;
},
{
orderid = 6748;
},
)
This should work
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"orderid.intValue" ascending:NO ];
[self.orderArray sortUsingDescriptors:#[sortDescriptor]];
I am agree with the #HotLicks this code must work. Are you sure between the sort code and log there is no code. If there is than please add it.
Only problem i see is that You have added your array name instead of NSArray in [self.orderArray sortUsingDescriptors:[self.orderArray arrayWithObject:sortDescriptor]]; this line.
Do it like this :
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"orderid" ascending:FALSE];
[self.orderArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; //Change in this line
[sortDescriptor release];
NSLog(#"self.orderArray : %#",self.orderArray);
You can sort an array using your "custom" comparator.
NSMutableArray *nds = [[NSMutableArray alloc] initWithArray:nodes];
//
[nds sortUsingComparator:^NSComparisonResult(Node *f1,Node *f2){
if (f1.nodeType == FOLDER && f2.nodeType == FILE) {
return NSOrderedAscending;
} else if (f1.nodeType == FILE && f2.nodeType == FOLDER) {
return NSOrderedDescending;
} else if (f1.nodeType == f2.nodeType) {
return [f1.displayName localizedCaseInsensitiveCompare:f2.displayName];
}
//
return [f1.displayName compare:f2.displayName];
}];
This method will traverse the array, taking two objects from the array and comparing them.
The advantage is that the objects can be of any type (class) and you decide the order between the two.
In the above example I want to order:
- folders before files
- folders and files in alphabetical order
I am trying to sort the array of SKProduct I received from Apple Server after sending the list of product id.
I want to sort just by using the following:
NSSortDescriptor *lowestPriceToHighest = [NSSortDescriptor sortDescriptorWithKey:#"self.price" ascending:YES];
NSArray *sortedProducts = [products sortedArrayUsingDescriptors:[NSArray arrayWithObject:lowestPriceToHighest]];
but i got the error message: Unable to access variable "lowestPriceToHighest"
Is my sort descriptor defined wrongly?
Swift 4:
products.sort(by: { (p0, p1) -> Bool in
return p0.price.floatValue < p1.price.floatValue
})
Try to remove "self"
NSSortDescriptor *lowestPriceToHighest = [NSSortDescriptor sortDescriptorWithKey:#"price" ascending:YES];
NSArray *sortedProducts = [products sortedArrayUsingDescriptors:[NSArray arrayWithObject:lowestPriceToHighest]];
Assuming you have var products: [SKProduct] you can do:
products.sortInPlace {
return Float($0.price) < Float($1.price)
}
Try:
NSArray *products = [response.products sortedArrayUsingComparator:^(id a, id b) {
NSDecimalNumber *first = [(SKProduct*)a price];
NSDecimalNumber *second = [(SKProduct*)b price];
return [first compare:second];
}];
from this answer:
how to sort products by price In App Purchases?
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"_strPrice"
ascending:sortFlag selector:#selector(localizedStandardCompare:)] ;
Try with this selector