How to sort non-english strings using nspredicate?

I am sorting the results of a fetch request with a sort descriptor.

NSFetchRequest* req = [[NSFetchRequest alloc] initWithEntityName:[MyEntity entityName]];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"property" 
                                                           ascending:YES 
                                                            selector:@selector(localizedCompare:)];
req.sortDescriptors = [NSArray arrayWithObject:descriptor];
return [self.managedObjectContext executeFetchRequest:req error:nil];

The problem is that words that start with non-English characters such as "İ" are listed at the end of the list. This is a Turkish letter, and the alphabet is as follows:

A, B, C, Ç, D, E, F, G, Ğ, H, I, İ, J, K, L, M, N, O, ..., P, R, S, Ş, T, U, x, V, Y, Z.

So, the letter is in the 12th position.

I do not know why, but using a comparator after the objects are loaded. Therefore, it works with any array, but not with a sort descriptor for querying a selection.

+5
source share
3 answers

NSFetchedResultsController v.s. UILocalizedIndexedCollation , UILocalizedIndexedCollation UILocalizedIndexCollation. , .

UILocalizedIndexCollation, localizedStandardCompare: not localizedCompare, WWDC .

+3

Try

[NSSortDescriptor alloc] initWithKey:@"property" ascending:YES selector:@selector(localizedCompare:)]

@Mert . , localizedCompare: , .

, . , , , :

// Create some entities:
NSArray *a = @[@"İ", @"J", @"Ğ", @"G", @"H", @"I", @"Ç", @"C"];
for (NSString *s in a) {
    MyEntity *e = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity"
                                                inManagedObjectContext:self.managedObjectContext];
    e.name = s;
}

// Fetch all entities in sorted order:
NSFetchRequest* req = [[NSFetchRequest alloc] initWithEntityName:@"MyEntity"];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
                                                           ascending:YES
                                                            selector:@selector(localizedCompare:)];
req.sortDescriptors = [NSArray arrayWithObject:descriptor];
NSArray *result = [self.managedObjectContext executeFetchRequest:req error:nil];

"MyEntity" - Core Data "name" String.

+1

I had problems with:

[strArr sortedArrayUsingSelector:@selector(localizedCompare:)]

It seems that

localizedCompare

causes

compare:other options:nil range:NSMakeRange(0, self.length) locale: [NSLocale currentLocale]];

[NSLocale currentLocale]may be in a mixed state depending on user preferences. To do this, you need to create a clean NSLocalebased on the language of users

Try creating a category on NSStringwith the following content:

-(NSComparisonResult)currentLocalCompare:(id)other
{
    NSLocale * currLoc = [NSLocale currentLocale]; //get current locale
    NSLocale * loc = [[NSLocale alloc] initWithLocaleIdentifier:currLoc.localeIdentifier];//lets create a new clean NSLocale based on users prefared langauge
    return [self compare:other options:nil range:NSMakeRange(0, self.length) locale:loc];//compare using clean NSLocale
}

and name it like this:

[strArr sortedArrayUsingSelector:@selector(currentLocalCompare:)]

0
source

All Articles