Objective C custom compare: with priority - ios

I have a NSArray of countries that I obtained using [NSLocale ISOCountryCodes]. How do I sort this NSArray such that I can put certain commonly used countries at the top of the list, while keeping the rest in its alphabetical order?
United States of America
United Kingdom
Singapore
Korea
Japan
Hong Kong
Afghanistan
Albania
Algeria
etc etc..
I am using caseInsensitiveCompare: currently to get the alphabetical order, but how can I change it such that I can specify a list to put at the top, while the rest to be kept alphabetical below.

You can delete the objects you do not want to sort,then sort the rest,then add them together.
Example Code:
NSMutableArray * allData = [[NSMutableArray alloc] initWithArray:[[NSLocale ISOCountryCodes]]];
NSArray * yourexceptArray;
[allData removeObjectsInArray:yourexceptArray];
NSMutableArray * result = [[NSMutableArray alloc] initWithArray:yourexcepArray];
sortedArray = //Sort the allData as you like,then add it to result
[result addObjectsFromArray:sortedArray]

As opposed to WenchenHuang's answer (which is valid), I think you could do it with the help of sortedArrayUsingComparator.
Inside the block just compare the strings as usually, but if the string equals to one of the codes that you want to show higher, return YES.
someArray = [someArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
if ([(NSString*)obj1 isEqualToString:#"USA"]) {
return YES;
} else if ([(NSString*)obj1 isEqualToString:#"SOME_OTHER_COUNTRY"]) {
return YES;
}
return [(NSString*)obj1 compare:(NSString*)obj2];
}];

I would do it using Sort Descriptor. I don't like manipulating array again and again. So, I find sort descriptors best in this kind of scenario. (Just personal preference)
Step 1: Create a model class with priority as a key. My model class-
#import <Foundation/Foundation.h>
#interface ISOCountry : NSObject
#property(nonatomic, strong) NSString *countryCode;
#property(nonatomic, retain) NSString *priority;
#end
Step 2: The just do this-
NSArray *ISOCountryCodes = [[NSArray alloc]initWithArray:[NSLocale ISOCountryCodes]];
NSArray *commonUsedCountries= [[NSArray alloc]initWithObjects:#"NR", #"NG", #"KW", #"ES", nil];
NSMutableArray *arrayToBeSorted = [[NSMutableArray alloc]init];
for(NSString *countryCode in ISOCountryCodes){
ISOCountry *isoCountry = [[ISOCountry alloc] init];
[isoCountry setValue:countryCode forKey:#"countryCode"];
if(![commonUsedCountries containsObject:countryCode]){
[isoCountry setValue:[NSString stringWithFormat:#"%d", 2] forKey:#"priority"];
}
else{
[isoCountry setValue:[NSString stringWithFormat:#"%d", 1] forKey:#"priority"];
}
[arrayToBeSorted addObject:isoCountry];
}
NSSortDescriptor *prioritySort = [[NSSortDescriptor alloc] initWithKey:#"priority" ascending:YES];
NSSortDescriptor *countryCodeSort = [[NSSortDescriptor alloc] initWithKey:#"countryCode" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:prioritySort, countryCodeSort, nil];
NSArray *sortedArray = [arrayToBeSorted sortedArrayUsingDescriptors:sortDescriptors];

Related

Sorting an array based on a compare model iOS

Student *s1 = [Student new];
s1.city = #"Delhi";
Student *s2 = [Student new];
s2.city = #"Mumbai";
NSArray *arrModels = #[s1,s2];
NSArray *arrCompareModel = #[#"Mumbai",#"Delhi"];
I need to sort the arrModels based on arrCompareModel.
All solutions in web are related to ascending. But here I have a custom model.
How do I achieve it?
You need to write this for sorting descending
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"city" ascending:false];
NSArray *sortedArray = [arrModels sortedArrayUsingDescriptors:#[sortDescriptor]];
Try something like that:
NSArray *sortedArray = [arrModels sortedArrayUsingComparator:^NSComparisonResult(Student *obj1, Student *obj2) {
return [arrCompareModel indexOfObject:obj1.city] < [arrCompareModel indexOfObject:obj2.city];
}];

How can we set DateAndTime at Ascending in ios

Hi i am new for ios and i am integrating my app with services and i am getting here trip creation TimeandDate values and storing that values one separate Array and also i am getting pickUpAdress values from services and storing them one separate arrayList
After storing in arrayList i am set date values at "Ascending" order in my tableList
after set "Ascending" when i display them in tableList both array-list data they are mismatching to one another please help me how can i resolve this problem how can i set my Adrress array values for matching to related DateandTimes
code:-
#import "ViewController.h"
#interface ViewController ()
{
NSSortDescriptor* sortOrder;
NSArray * ToBeReadyTimeArray1;
NSMutableArray * ToBeReadyTimeArray ,*finalToBeReadyTimeArray,*AdressArray;
UITableView * MaintableView;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ToBeReadyTimeArray1 = [[NSArray alloc]init];
ToBeReadyTimeArray = [[NSMutableArray alloc]initWithObjects:#"02/17/2016",#"03/13/2016",#"04/18/2016",#"05/21/2016", nil];
finalToBeReadyTimeArray =[[NSMutableArray alloc]init];
AdressArray = [[NSMutableArray alloc]initWithObjects:#"Adress1",#"Adress2",#"Adress3",#"Adress4", nil];
//Arange Date formate At Assending order:-
sortOrder = [NSSortDescriptor sortDescriptorWithKey: #"self" ascending: YES];
ToBeReadyTimeArray1 = [ToBeReadyTimeArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
for (NSString *dte in ToBeReadyTimeArray1){
NSDateFormatter *aDateFormatter = [[NSDateFormatter alloc] init];
[aDateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[aDateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate * parsed = [aDateFormatter dateFromString:dte];
[aDateFormatter setDateFormat:#"dd MMM yyyy"];
NSString *aFormattedElapsedTime = [aDateFormatter stringFromDate:parsed];
NSLog(#"tobe Ready time %#",aFormattedElapsedTime);
[finalToBeReadyTimeArray addObject:aFormattedElapsedTime];
}
}
I presume you are trying to list pick up times / address with some sorted order. If that's so, i would have created a NSArray of Booking or Trip models which would contain the information as Address (NSString *) and PickUpTime (NSDate *) and then would have implemented a sorting method using the property as variable key.
In my case, I implemented an array of booking models which has pickUpTime and address.
#property (nonatomic, retain) NSNumber *pickUpTime; // Timestamp instead of NSDate ...
#property (nonatomic, retain) NSString *address;
I implemented a category method for NSArray. Please note that sort order enumerations are manually implemented.
+ (NSArray *)sortArray:(NSArray *)unSortedArray byOrder:(SortOrder)sortOrder usingVariableKey:(NSString *)variableKey {
NSArray *sortedArray = [NSArray array];
BOOL isAscendingOrder = NO;
if (sortOrder == SortOrderAscending) {
isAscendingOrder = YES;
}
if (unSortedArray) {
NSSortDescriptor *valueDescriptor = [[NSSortDescriptor alloc] initWithKey:variableKey ascending:isAscendingOrder];
NSArray *descriptors = [NSArray arrayWithObject:valueDescriptor];
sortedArray = [[unSortedArray sortedArrayUsingDescriptors:descriptors] mutableCopy];
}
return sortedArray;
}
Then, i invoked the following ...
// Here, resultMutableArray is a mutable array of booking models ...
NSArray *resultArray = [NSArray sortArray:[resultMutableArray copy] byOrder:SortOrderDescending usingVariableKey:#"pickUpTime"];

How to sort UITableView sections

I have an array of objects with date inside.
Now I need to group my objects in UITableView by this date.
For examle:
0-{10-14; Obj1};
1-{10-14; Obj2};
2-{10-15; Obj3};
3-{10-15; Obj4};
I need to view it on my UITableView like this
10-14
0-{10-14; Obj1};
1-{10-14; Obj2};
10-15
2-{10-15; Obj3};
3-{10-15; Obj4};
To resolve I've done next; I've splited my array into NSDictationary with this code:
NSMutableDictionary *preResult = [[NSMutableDictionary alloc] init];
for (ClientMessage *message in array) {
NSMutableArray *mArray = [preResult objectForKey:message.formattedDate];
if (mArray == nil) {
mArray = [[NSMutableArray alloc] init];
[preResult setObject: mArray forKey:message.formattedDate];
}
[mArray addObject:message];
}
And my Table view shows me what i want, but it shows in wrong order; (my array was sorted by date)
I know tha i can't sort NSDictationary, in that case how can i sort my values in table view? Or Is there another way to group my values without NSDictationary?
Once you've finished loading the dictionary with all the values, you'll want to sort each array within the dictionary...
for (NSString *key in [preResult allKeys])
{
NSMutableArray *mArray = [preResult objectForKey:key];
// sort array to achieve the desired result
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"formattedDate" ascending:YES];
NSArray *sortedArray = [mArray sortedArrayUsingDescriptors:#[sortDescriptor]];
// reset newly sorted array for key inside the dictionary
[preResult sortedArray forKey:key];
}

NSMutableArray and addObject - Sublist

How can I have sub lists using NSMutableArray and addObject:
Here is the current code:
categories = [[NSMutableArray alloc] init];
[categories addObject:#"Line 1"];
[categories addObject:#"Line 2"];
[categories addObject:#"Line 3"];
[categories addObject:#"Line 4"];
I would like to have sublisting like so:
Line 1
Line A
Line B
Line C
Line 2
Line A
Line B
Line C
...etc...
Let me know if this is possible and how. Thanks.
You're just adding strings to an array. If you want a list within a list, you have to create the sublist and then add it as an object within the main list
NSMutableArray *mainList = [NSMutableArray new];
NSArray *subList = #[#"thing 1",#"thing 2",#"thing 3"];
[mainList addObject:subList];
Then, if you want to access and individual subArray, you could do so like this:
NSArray *subList = mainList[0];
Or an individual sublist item:
NSString *item = mainList[0][1];
Which would be the second item in the first sublist.
You need to create an object, let's say MyObject, which contains a string and another Array
#interface MyObject
#property NSString *name;
#property NSMutableArray *items;
#end
and add MyObject objects to your categories array.
you can do it like this:
NSMutableArray *categories = [[NSMutableArray alloc] init];
NSArray *LineOne = #[#"Line A",#"Line B",#"Line C"];
NSArray *LineTwo = #[#"Line A",#"Line B",#"Line C"];
[categories addObject:LineOne];
[categories addObject:LineTwo];
Looks like NSMutableDictionary is your solution:
NSMutableDictionary * dict = [NSMutableDictionary new];
NSArray *line1list, *line2list, *line3list;
// init list arrays
[dict setObject:line1list forKey:#"Line 1"];
[dict setObject:line2list forKey:#"Line 2"];
[dict setObject:line3list forKey:#"Line 3"];

Sort an array based on another configuration array

I have to sort an arrray according to configuration , Suppose its has some data of student which has student name
[NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:#"abc",#"name", nil],[NSDictionary dictionaryWithObjectsAndKeys:#"efg",#"name", nil][NSDictionary dictionaryWithObjectsAndKeys:#"cde",#"name", nil], nil];
and i have another array which say how to sort this array like its say first should be efg then abc and so on.
Is it possible using nsssortdescriptor or i have to write my custom code.
I would use a block to allow you to specify your comparison logic
NSArray *sortedArray = [_helpItems sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
return [(MAHelpItem *)a order] > [(MAHelpItem *)b order];
}];
self.items = sortedArray;
Perhaps this is what you're looking for:
NSArray *students;
NSArray *sortPriorities;
NSMutableArray *sortDescriptors = #[].mutableCopy;
for (NSString *key in sortPriorities) {
[sortDescriptors addObject:[NSSortDescriptor sortDescriptorWithKey:key ascending:YES]];
}
NSArray *sortedStudents = [students sortedArrayUsingDescriptors:sortDescriptors];

Resources