I have data collection(NSArray) of NSDictionary. Now in the app i need to show that data in three different sorting order. Now I do not want to make 3 different array (one for each sorting order with complete data) because it will consume memory nor I want to re-sort main array each time when user change sorting option.
so now my problem is, I want a mechanism that I can only get indexes of main array in 3 different array(or any other datatype) in 3 different sorting order. Should I have to do this manually or is there a build in method for geting sorted index array from main array?
-
Why don't want to sort main array each time user changes the sort Order?Anupdas– Anupdas2013-05-02 07:49:58 +00:00Commented May 2, 2013 at 7:49
-
i think its waste of cpu power.Iqbal Khan– Iqbal Khan2013-05-02 11:08:06 +00:00Commented May 2, 2013 at 11:08
-
I think this computation would be very minimal and you are making a straight forward sorting more complex. Do profiling, if it's a real issue, then look for other ways to optimize this.Anupdas– Anupdas2013-05-02 11:23:20 +00:00Commented May 2, 2013 at 11:23
5 Answers
What you're asking is impossible. You want to have your items sorted in 3 different orders without saving them into different arrays AND without sorting them every time the sorting method changes.
You can't get it for free. You can pay either with memory or with performance. I'd go for memory, since it's not as costly as you think. Only the pointers to the NSDictionaries are kept in your array, so it shouldn't take too much memory.
1 Comment
NSArray takes only objects as its elements. And objects pointers are stored in the array. So I guess, the option you are talking about, saving indexes in another array is something similar like saving pointers in sorting order. So, you have create 3 different arrays with the pointers to objects in a particular order, it will be the same, not taking more memory. When you copy the sorted objects in new arrays, the objects will not be allocated again, only their pointers will be stored. However you have to do the sorting in right way.
Comments
If you want to keep your data in a single array, then you can use an NSMutableArray and (re-)sort it whenever the sort criteria changes.
Notice however that this means that if your data array is part of your model, and your sorting order is a presentation (UI) issue, then you are effectively mixing model, view and controller functionality in one object. Bad ( :-) ) but not the first time it has happened in history.
Here is an example using sort descriptors directly on keys of your dictionaries:
NSMutableArray *data = // ... your data as a mutable array
NSString* sortKey = // ... one of the 3 dictionary keys that you wish to sort by
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:sortKey ascending:YES];
[data sortUsingDescriptors:@[sd]];
The data array is now sorted without using an extra array variable.
Comments
Step1 : Declare Enum Definition before import statement
enum COMP_TYPE {
LOCALIZE_COMPARE = 1,
CASE_INSENSITIVE = 2,
LOCALIZE_CASE_INSENSITIVE = 3
};
Step2 : Define following function in your .m file
-(NSArray *)sortArray:(NSArray *)arr WithType:(int)type andKey:(NSString *)key andOrder:(BOOL)order
{
SEL _compareSelector;
switch (type) {
case LOCALIZE_COMPARE:
_compareSelector = @selector(localizedCompare:);
break;
case CASE_INSENSITIVE:
_compareSelector = @selector(caseInsensitiveCompare:);
break;
case LOCALIZE_CASE_INSENSITIVE:
_compareSelector = @selector(localizedCaseInsensitiveCompare:);
break;
default:
break;
}
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:key ascending:order selector:_compareSelector];
return [arr sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
}
Step3 : Declare your Array of Dictionary
NSArray *myArr = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:@"stack", @"name",
@"goa", @"name1",nil],
[NSDictionary dictionaryWithObjectsAndKeys:@"stack", @"name",
@"goa", @"name1",nil],
[NSDictionary dictionaryWithObjectsAndKeys:@"objective", @"name",
@"c++", @"name1",nil], nil];
Step4 : call function with diferent Parameter
NSLog(@"%@",[self sortArray:myArr WithType:LOCALIZE_COMPARE andKey:@"name" andOrder:YES]);
NSLog(@"%@",[self sortArray:myArr WithType:CASE_INSENSITIVE andKey:@"name" andOrder:YES]);
NSLog(@"%@",[self sortArray:myArr WithType:LOCALIZE_CASE_INSENSITIVE andKey:@"name" andOrder:YES]);