如何使用 nspredicate 对非英语字符串进行排序?
Posted
技术标签:
【中文标题】如何使用 nspredicate 对非英语字符串进行排序?【英文标题】:How to sort non-english strings using nspredicate? 【发布时间】:2012-08-05 07:01:21 【问题描述】:我正在使用排序描述符对获取请求的结果进行排序。
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];
问题在于以“İ”等非英语字符开头的单词列在列表末尾。这是一个土耳其字母,字母表如下所示:
A、B、C、Ç、D、E、F、G、Ğ、H、I、İ、J、K、L、M、N、O、Ö、P、R、S、Ş、T , U, Ü, V, Y, Z。
所以字母在第 12 位。
我不知道为什么,但是在获取对象后使用比较器是可行的。所以它适用于任何数组,但不适用于获取请求的排序描述符。
【问题讨论】:
【参考方案1】:在NSFetchedResultsController v.s. UILocalizedIndexedCollation 上查看我的问题的详细信息,我将展示如何使用 UILocalizedIndexedCollation 正确生成 Alphabet 并使用基于 UILocalizedIndexCollation 的正确排序方法进行排序。我的问题只是围绕着寻求一种更好的方法来做到这一点。
如果您不使用 UILocalizedIndexCollation,您应该只使用 localizedStandardCompare:而不是 WWDC 视频中提到的本地化比较进行本地化。
【讨论】:
【参考方案2】:试试
[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”是一个核心数据实体,具有一个字符串类型的属性“名称”。
【讨论】:
它没有用。我也试过改变模拟器的语言。 这很奇怪。如果我使用[myArray sortedArrayUsingSelector:@selector(localizedCompare:)]
对数组进行排序,那么我会得到正确的结果。你能展示你如何设置获取请求的代码吗?
我以几乎相同的方式完成了它(使用获取的结果控制器),它适用于德语变音符号和其他国际字符。顺便说一句:您是否使用 ARC 编译?
我已经尝试过了,但会再次询问您在项目设置中的本地化原生开发区域是什么?是的,我正在使用 ARC 进行编译
localizedCompare 函数从哪里获取语言?【参考方案3】:
我遇到了类似的问题:
[strArr sortedArrayUsingSelector:@selector(localizedCompare:)]
好像
localizedCompare
来电
compare:other options:nil range:NSMakeRange(0, self.length) locale: [NSLocale currentLocale]];
[NSLocale currentLocale]
可能处于混合状态,具体取决于用户的偏好。因此需要根据用户语言创建一个干净的NSLocale
尝试在NSString
上创建一个包含以下内容的类别:
-(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
然后这样称呼它:
[strArr sortedArrayUsingSelector:@selector(currentLocalCompare:)]
【讨论】:
以上是关于如何使用 nspredicate 对非英语字符串进行排序?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用正则表达式搜索忽略 NSPredicate 的某些字符?