This question already has answers here:
How to add these object with name to the array by this order?
(4 answers)
How to sort an array with alphanumeric values?
(4 answers)
How to get sorted NSArray from an NSArray that contains strings in this format "2.0.1", "2.0.09", "2.0.5"
(2 answers)
Closed 5 years ago.
I have a NSMutableArray called allItems which has the following ProductData object.
Each object has cid, cname, ctype and cimage. As you see below json object is not coming in order. However, cid is a indicator for ordering.
I wonder how do you order based on cid?
[
{
"cid": "2",
"cname": "Meats",
"ctype": "main",
"cimage": "baked_chicken.jpg"
},
{
"cid": "1",
"cname": "Dips",
"ctype": "side",
"cimage": "stuffed_eggplant.jpg"
},
{
"cid": "4",
"cname": "Sandwiches",
"ctype": "sand",
"cimage": "chickenshawarma.jpg"
},
{
"cid": "3",
"cname": "Appetizers",
"ctype": "side",
"cimage": "rice_lentils.jpg"
},
{
"cid": "5",
"cname": "Desserts",
"ctype": "dsrt",
"cimage": "cake.jpg"
}]
If I use the sortDescriptior, it partially works. The issue that I am facing, when it sorts, it first display cid 1 and then cid 10 and then cid 2.
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"cid" ascending:YES];
[allItems sortUsingDescriptors:#[sortDescriptor]];
Use a sort descriptor with a comparator passing compare:options: and option NSNumericSearch:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"cid" ascending:YES comparator:^(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
or even simpler:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"cid" ascending:YES selector:#selector(localizedStandardCompare:)];
localizedStandardCompare is a special comparison selector:
This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact sorting behavior of this method is different under different locales and may be changed in future releases. This method uses the current locale.
Use this
NSSortDescriptor *aSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"cid" ascending:YES comparator:^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([obj1 integerValue] < [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
sortedArray = [NSMutableArray arrayWithArray:[unsortedArray sortedArrayUsingDescriptors:#[aSortDescriptor]]];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"cId"
ascending:YES selector:#selector(caseInsensitiveCompare:)];
arrToBeSort = [arrToBeSort sortedArrayUsingDescriptors:[NSArray
descriptor]];
this will work
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"cid.intValue" ascending:YES];
[array sortUsingDescriptors:#[sortDescriptor]];
Your "array" has now been sorted after print it
Printing description of array: <__NSArrayM 0x618000041bf0>( { cid = 1; cimage = "stuffed_eggplant.jpg"; cname = Dips; ctype = side; }, { cid = 2; cimage = "baked_chicken.jpg"; cname = Meats; ctype = main; }, { cid = 3; cimage = "rice_lentils.jpg"; cname = Appetizers; ctype = side; }, { cid = 4; cimage = "chickenshawarma.jpg"; cname = Sandwiches; ctype = sand; }, { cid = 5; cimage = "cake.jpg"; cname = Desserts; ctype = dsrt; } )
Related
I have array that have dictionaries, for exp..
[
{
name : dilip
},
{
address : ahmedabad
},
{
name : ajay
},
{
address : baroda
},
{
name : ram
},
{
address : dwarka
},
.
.
.
]
Now i want to sort this array alphanumerically,Like this..
(
{
address = ahmedabad;
},
{
name = ajay;
},
{
address = baroda;
},
{
name = dilip;
},
{
address = dwarka;
},
{
name = ram;
}
)
But if any Dictionary does not have name than it will be sorted using address,
Any suggestion that how can we do it?
I have tried following code, but not getting proper result,
NSSortDescriptor * brandDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSSortDescriptor * productTitleDescriptor = [[NSSortDescriptor alloc] initWithKey:#"address" ascending:YES];
NSArray * sortDescriptors = [NSArray arrayWithObjects:brandDescriptor, productTitleDescriptor, nil];
NSArray * sortedArray = [ary sortedArrayUsingDescriptors:sortDescriptors];
I have 1 idea, that add address string in name and than sort array and once array sorted than will change it back to address,
But want to know is there any other option or not.
Think this might do the trick
NSArray * sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(NSDictionary * _Nonnull obj1, NSDictionary * _Nonnull obj2) {
NSString * s1 = [obj1 objectForKey:#"name"];
if(s1 == nil){
s1 = [obj1 objectForKey:#"address"];
}
NSString * s2 = [obj2 objectForKey:#"name"];
if(s2 == nil){
s2 = [obj2 objectForKey:#"address"];
}
return [s1 compare:s2];
}];
havnt tested the code so may need some tweaking
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
This question already has answers here:
Sorting NSArray of dictionaries by value of a key in the dictionaries
(11 answers)
Closed 9 years ago.
Suppose I would like to sort array by "firstName" key.
Example
Array = (
{
People1 = {
firstName = #"Jack Adam";
email = #"adam#gmail.com";
};
Address = {
cityCode = #"TH";
};
},
People2 = {
firstName = #"Jack DAm";
email = #"dam#gmail.com";
};
Address = {
city = #"TH";
};
);
user Sort Comparator
NSArray *sortedArray = [unsortedArray sortedArrayUsingComparator:^(NSDictionary *a, NSDictionary *b) {
return [a[#"People"][#"firstname"] compare:b[#"People"][#"firstname"]];
}];
But Your Key is inconsistency ...
I Think that data should be
Array = (
{
People = {
firstName = #"Jack Adam";
email = #"adam#gmail.com";
};
Address = {
cityCode = #"TH";
};
},
People = {
firstName = #"Jack DAm";
email = #"dam#gmail.com";
};
Address = {
city = #"TH";
};
);
Using blocks and modern Objective-C syntax:
NSArray *sortedArray = [unsortedArray sortedArrayUsingComparator:^(NSDictionary *first, NSDictionary *second) {
return [first[#"Person"] compare:second[#"Person"]];
}];
Using NSSortDescriptor:
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"firstName" ascending:YES];
myArray=[stories sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];
temp = [stories copy]; //temp is NSMutableArray
myArray is the array you want to sort.
First,you should implement a compare-method for your object.
- (NSComparisonResult)compare:(Person *)otherObject {
return [self.birthDate compare:otherObject.birthDate];
}
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingSelector:#selector(compare:)];
As you replied in a comment, the first dictionary key is "Person1" in all array elements.
Then "Person1.firstName" is the key path that gives the first name of each array
element. This key path can be used in a sort descriptor:
NSArray *array = ... // your array
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"Person1.firstName" ascending:YES];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:#[sort]];
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