How to sort array using 2 key - ios

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

Related

Order an array based on one property [duplicate]

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; } )

Filter NSArray to make new NSArray for use on tableview methods

I have a NSArray that looks like this:
{"result":
[
{
"epoch":"1371333600"
},
{
"epoch":"1371420000"
},
{
"epoch":"1371333600"
}
]
}
I want to sort the NSArray and make a new one so i can use it easier with the tableview methods to count the sections and rows.
All the dates that are the same need to be in one section.
The array should look like the example below but i don’t know how to get there. I have tried NSPredicate and used a loop but it won’t work.
What i want:
{"result":
[
{"data":
[
{
"epoch":"1371333600"
},
{
"epoch":"1371333600"
}
]
},
{"data":
[
{
"epoch":"1371420000"
}
]
}
]
}
My NSPredicate looks like this, but does not give me the result.
_finalArray = [[NSMutableArray alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"epoch IN %#", [_resultArray valueForKey:#"epoch"]];
_predicateDate = [NSMutableArray arrayWithArray:[dataSortArray filteredArrayUsingPredicate:predicate]];
if ([_predicateDate count] != 0)
{
NSDictionary *itemsArrayDict = [NSDictionary dictionaryWithObject:_predicateDate forKey:#"data"];
[_finalArray addObject:itemsArrayDict];
}
NSOrderedSet is awesome for this occasion as it allows you to get the unique strings.
NSDictionary *dict1 = [NSDictionary dictionaryWithObject:#"2222222" forKey:#"epoch"];
NSDictionary *dict2 = [NSDictionary dictionaryWithObject:#"2222222" forKey:#"epoch"];
NSDictionary *dict3 = [NSDictionary dictionaryWithObject:#"1111111" forKey:#"epoch"];
NSArray *dictArray = #[dict1, dict2, dict3];
NSMutableArray *finalArray = [[NSMutableArray alloc]init];
NSArray *epoches = [dictArray valueForKey:#"epoch"];
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:epoches];
for (NSString *string in orderedSet) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"epoch == %#", string];
NSArray *resultsArray = [dictArray filteredArrayUsingPredicate:predicate];
[finalArray addObject:resultsArray];
}
Hi you can use the NSPredicate to filter an array like:
//NSPredicate to filter an array
NSArray *data = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:#"hello" forKey:#"Test"]];
NSArray *filtered = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(Test == %#)", #"hello"]];
Thanks
It appears that you are using dictionaries along with arrays. Here's what I've achieved:
(result
(data
{
epoch = 1371333600;
},
{
epoch = 1371333600;
}
),
(data
{
epoch = 1371420000;
}
)
)
I'm not using predicates, but it looks as it's working :). Here is the code:
// Initial input
NSArray *result = #[#{#"epoch":#"1371333600"},#{#"epoch":#"1371420000"},#{#"epoch":#"1371333600"}];
// Get unique values for the input
NSSet *resultSet = [NSSet setWithArray:result];
// Here we are going to store the final result
NSMutableArray *newResult = [[NSMutableArray alloc] init];
// Loop over the unique items
for (NSDictionary *uniqueItem in resultSet) {
// Here we are going to store the grouped data
NSMutableArray *dataResult = [[NSMutableArray alloc] init];
// Loop over the initial input
for (NSDictionary *resultItem in result) {
// Search for all the items that are equal to the uniqe
// I would rather include a count instead of repeating values :)
if([uniqueItem isEqual:resultItem]) {
[dataResult addObject:resultItem];
}
}
[newResult addObject:dataResult];
}
NSLog(#"%#", newResult);
Cheers!

How to sort Array containing that contains NSDictionaries [duplicate]

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]];

NSSortDescriptor not sorting my NSMutableArray?

I have an NSMutableArray that has NSDictionaries in it. I found a question on SO, and am using this code to sort this NSMutableArray:
NSMutableArray
{
data = {
etc... (for length)
};
number = 1;
},
{
data = {
etc... (for length)
};
number = 3;
},
{
data = {
etc... (for length)
};
number = 4;
},
{
data = {
etc... (for length)
};
number = 2;
}
This array goes up to 80 sub Dictionaries.
NSSortDescriptor
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"number" ascending:YES];
[NSMUTABLEARRAYVAR sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];
NSMutableArray *test;
test = [NSMUTABLEARRAYVAR copy];
When I NSLog "test" I get the same order as NSMUTABLEARRAYVAR???
I would appreciate any help in solving this issue, thanks!
sortedArrayUsingDescriptors does not sort the array in place. It returns a newly-sorted array.
sortUsingDescriptors does an in-place sort.

sorting a nested NSMutableArray

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

Resources