【问题标题】:How to sort non-english strings using nspredicate?如何使用 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 位。

我不知道为什么,但是在获取对象后使用比较器是可行的。所以它适用于任何数组,但不适用于获取请求的排序描述符。

【问题讨论】:

    标签: objective-c ios cocoa-touch core-data nssortdescriptor


    【解决方案1】:

    NSFetchedResultsController v.s. UILocalizedIndexedCollation 上查看我的问题的详细信息,我将展示如何使用 UILocalizedIndexedCollat​​ion 正确生成 Alphabet 并使用基于 UILocalizedIndexCollat​​ion 的正确排序方法进行排序。我的问题只是围绕着寻求一种更好的方法来做到这一点。

    如果您不使用 UILocalizedIndexCollat​​ion,您应该只使用 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:)]

      【讨论】:

        猜你喜欢
        • 2017-05-04
        • 2011-10-03
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 1970-01-01
        • 2014-10-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多