NSSortDescriptor with custom sorting

I can’t shrug my head over how to do arbitrary sorting using NSSortDescriptor.

I want to do something like this:

NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"@", @"#", @"!", @"&", @"r", @"a", nil]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES comparator: ^(id obj1, id obj2) { NSComparisonResult comparisonResult; //Some code that uses sortAlgorithm. return comparisonResult; } ]; 

This sorts objects by the name key, so any key starting with @ , for example. @home , appears before any key starting with r , for example. radical , and this will happen again before any key starting with a , for example. anything .

The above example. The point is to allow completely arbitrary sorting.

This should be used for the NSFetchedResultsController.

What will happen to the code for some code that uses sortAlgorithm?

EDIT:

The code surrounding my attempt to implement sortDescriptor, like occulus' :

 - (NSFetchedResultsController *)fetchedResultsController { if (__fetchedResultsController) return __fetchedResultsController; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; fetchRequest.entity = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:self.temporaryManagedObjectContext]; //NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO comparator:^(id obj1, id obj2) { NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"#", @"!", @"@", @".", nil]; NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1]; NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1]; int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar]; int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar]; if ( idx1 < idx2 ) return NSOrderedAscending; else if ( idx1 > idx2 ) return NSOrderedDescending; else return NSOrderedSame; }]; fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; fetchRequest.fetchBatchSize = 20; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.temporaryManagedObjectContext sectionNameKeyPath:nil cacheName:@"Tags"]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; [self.fetchedResultsController performFetch:nil]; return __fetchedResultsController; } 

The recorded sortDescriptor handler works.

A property is defined called name on the objects of the Tag object. But even if it weren’t, this does not seem to be a problem. Xcode doesn't seem to even compile this line of code (sortDescriptor), which sounds funny. Breakpoints work fine, but don't break on this particular line of code.

+4
source share
1 answer

You need to pull the first characters of the strings obj1 and obj2 as NSStrings , find their indices in an arbitrary ordering array, and then compare the positions.

Something like this: (put this code in a ^ block)

 NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1]; NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1]; int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar]; int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar]; // NOTE: we haven't dealt with the case where one of the // chars wasn't found in the array of characters. A strategy // for this would need to be decided. if (idx1 == idx2) { return NSOrderedSame; } if (idx1 < idx2) { return NSOrderedAscending; } return NSOrderedDescending; 

Not tested, may require a little tweaking. Watch for differences in upper / lower case characteristics.

UPDATE: There seems to be problems using sort descriptors and SQL data stores. See this question for more information.

+3
source

Source: https://habr.com/ru/post/1383086/


All Articles