1

I have an NSArray of strings that I want to use as my sort order:

NSArray *permissionTypes = [NSArray arrayWithObjects:@"Read", @"Write", @"Admin", nil];

I then have a NSMutableArray that may or may not have all three of those permissions types, but sometimes it will only be 2, sometimes 1, but I still want it sorted based on my permissionsTypes array.

NSMutableArray *order = [NSMutableArray arrayWithArray:[permissions allKeys]];

How can I always sort my order array correctly based on my using the permissionTypes array as a key?

Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412
  • you can make use of the methods `sortUsingSelector:` or `sortUsingComparator:`, in this other question you can find more information http://stackoverflow.com/questions/1132806/sort-nsarray-of-date-strings-or-objects – tkanzakic Dec 03 '12 at 09:14
  • You could use `NSSortDescriptor` and/or `blocks`, as described [here](http://stackoverflow.com/a/805589/377384). – lindon fox Dec 03 '12 at 09:12

4 Answers4

3

I would go about this by creating a struct or an object to hold the permission types.

Then you can have...

PermissionType
--------------
Name: Read
Order: 1

PermissionType
--------------
Name: Write
Order: 2

and so on.

Then you only need the actual array of these objects and you can sort by the order value.

[array sortUsingComparator:^NSComparisonResult(PermissionType *obj1, PermissionType *obj2) {
        return [obj1.order compare:obj2.order];
    }];

This will order the array by the order field.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • I don't think it is that easy though. Even though I want Write in position 1, if the array I get only has 1 string in it, which is "Write", then obviously it would need to be in position 0. – Nic Hubbard Dec 03 '12 at 09:10
  • The "Order" value is only a sorting value. not an absolute position. I'll add the sort code... – Fogmeister Dec 03 '12 at 09:11
  • Shouldn't this also work? [order sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { return [[NSNumber numberWithInt:[permissionTypes indexOfObject:obj1]] compare:[NSNumber numberWithInt:[[permissions allKeys] indexOfObject:obj2]]]; }]; – Nic Hubbard Dec 03 '12 at 09:19
3
NSMutableArray *sortDescriptors = [NSMutableArray array]; 

for (NSString *type in permissionTypes) {
    NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:type ascending:YES] autorelease];

    [sortDescriptors addObject:descriptor];
}

sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors];
pbibergal
  • 2,901
  • 1
  • 17
  • 19
0

Use whichever sorting method on NSMutableArray you prefer, you will either provide a block or a selector to use for comparing two elements. In that block/selector rather than comparing the two strings passed in directly look each up in your permissionTypes array using indexOfObject: and compare the resulting index values returned.

CRD
  • 52,522
  • 5
  • 70
  • 86
0

I suggest you another approuch:

- (void)viewDidLoad
{
[super viewDidLoad];

arrayPermissions = [[NSMutableArray alloc] init];


NSDictionary *dicRead = [NSDictionary dictionaryWithObjectsAndKeys:
                              @"Read", @"Permission", nil];

NSDictionary *dicWrite = [NSDictionary dictionaryWithObjectsAndKeys:
                               @"Write", @"Permission", nil];

NSDictionary *dicAdmin = [NSDictionary dictionaryWithObjectsAndKeys:
                              @"Admin", @"Permission", nil];

NSLog(@"my dicRead = %@", dicRead);
NSLog(@"my dicWrite = %@", dicWrite);
NSLog(@"my dicAdmin = %@", dicAdmin);

[arrayPermissions addObject:dicRead];
[arrayPermissions addObject:dicWrite];
[arrayPermissions addObject:dicAdmin];

NSLog(@"arrayPermissions is: %@", arrayPermissions);

// create a temporary Dict again

NSDictionary *temp =[[NSDictionary alloc]
                     initWithObjectsAndKeys: arrayPermissions, @"Permission", nil];

// declare one dictionary in header class for global use and called "filteredDict"
self.filteredDict = temp;

self.sortedKeys =[[self.filteredDict allKeys]
                  sortedArrayUsingSelector:@selector(compare:)];


NSLog(@"sortedKeys is: %i", sortedKeys.count);
NSLog(@"sortedKeys is: %@", sortedKeys);

}

hope help

sundsx
  • 588
  • 9
  • 27
  • why are people so afraid about writing custom classes? it is kind of stupid to hold an extra array for the sorted keys if you just can stick the custom objects into an array and sort that. – vikingosegundo Apr 18 '13 at 15:20
  • Think before you say that. I see only one Array, perhaps too many dictionaries, but if you know the method that you suggest would not have asked. My suggestion is easy to understand and can be optimized once you understand the mechanics. Anyway, I appreciate your suggestion ... – sundsx Apr 18 '13 at 15:58
  • btw: how is sortedKeys helpful? it just contain one key. – vikingosegundo Apr 18 '13 at 16:31
  • do you like more? NSArray *sortedArrayXX; NSArray *permissionTypes = [NSArray arrayWithObjects:@"Read", @"Write", @"Admin", nil]; sortedArrayXX = [permissionTypes sortedArrayUsingSelector:@selector(compare:)]; NSLog(@"This is sortedArrayXX: %@", sortedArrayXX); – sundsx Apr 18 '13 at 16:42
  • Why sort an array, that only has one entry? do u want to put this object on the start or on the end? – vikingosegundo Apr 18 '13 at 16:44
  • In the first case is usefull, for example, in a table view enviroments with a users list and in section header appropriate privileges for different users: Admin, Write, Read. The seconds is an example for order entry. In this case text, but is possible number from rand()... Thats! – sundsx Apr 18 '13 at 16:57
  • either you should start thinking or you already think to much – vikingosegundo Apr 18 '13 at 16:59
  • all two! segundo.. see you – sundsx Apr 18 '13 at 17:02