【问题标题】:How can I do a case insensitive sort of NSFetchedResultsController that also ignores words like "the"?我怎样才能做一种不区分大小写的 NSFetchedResultsController 也忽略像“the”这样的词?
【发布时间】:2011-11-15 17:31:10
【问题描述】:

我正在开发一个 Core Data 驱动的应用程序,该应用程序在 NSFetchedResultsController 中有 2 个需要特殊排序注意事项的实体。

2 的更简单的情况只需要忽略“The”,因此(我引用的是真实数据示例)种植节在泥炭岭节之后按排序顺序排列。为了安全起见,我还想让这种大小写不敏感。对于那个我尝试了这里的建议How can I sort an NSTableColumn of NSStrings ignoring "The " and "A "? 添加...

@property (nonatomic, readonly) NSString * sortname;

到我的实体定义类的接口&...

- (NSString *)sortname
{
    NSMutableString *temp = [NSMutableString stringWithString:[[self name] lowercaseString]];
    if ([temp hasPrefix:@"the "]) {
        return [temp substringFromIndex:4];
    }
    return temp;
}

执行,但是当我将@"sortname" 作为NSSortDescriptor 的键时,应用程序崩溃。

第二个实体更复杂。除了剥离“The”进行排序之外,还有“A”和“Dr”和“Professor”等敬语,但并非总是如此。数据中的一个例子是 Ian Lowe 教授和 Wallace 教授的木偶剧院。 Ian Lowe 是一个真实的人,他(尽管我很尊重他)应该为 Ian 归类为 I,但没有华莱士教授,那只是一个木偶剧院的名字,它应该归类为 P。对于那个选择性一方面,除了实体上的布尔属性指定是否剥离第一个单词以进行排序之外,我没有其他办法。

对于剩下的问题,问题归结为...有没有办法在核心数据实体上创建一个(因为想知道更正确的术语)虚拟属性,当我将其名称作为NSSortDescriptorNSFetchedResultsController 的密钥?

我不想采取的绝望方法是在这 2 个实体上创建真正的 sortname 属性并在填充实体时计算值。

更新... 尝试遵循 TechZen 的回答,这是我的 NSFetchedResultsController 的构造函数...

- (NSFetchedResultsController *)frc
{
    if (_frc) return _frc;

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"EventProfile"
                                              inManagedObjectContext:_moc];
    [request setEntity:entity];
    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"name"
                                                           ascending:YES
                                                          comparator:^NSComparisonResult(id obj1, id obj2) {
        NSMutableString *sortname1 = [NSMutableString stringWithString:[obj1 lowercaseString]];
        if ([sortname1 hasPrefix:@"the "]) {
            sortname1 = [NSMutableString stringWithString:[sortname1 substringFromIndex:4]];
        }
        NSMutableString *sortname2 = [NSMutableString stringWithString:[obj2 lowercaseString]];
        if ([sortname2 hasPrefix:@"the "]) {
            sortname2 = [NSMutableString stringWithString:[sortname2 substringFromIndex:4]];
        }
        return [sortname1 compare:sortname2];
    }];

    [request setSortDescriptors:[NSArray arrayWithObject:sorter]];
    [sorter release], sorter = nil;
    [request setFetchBatchSize:15];

    NSFetchedResultsController *frcTemp = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                              managedObjectContext:_moc
                                                                                sectionNameKeyPath:nil
                                                                                         cacheName:[NSString GetUUID]];
    [self setFrc:frcTemp];
    [_frc setDelegate:self];
    [frcTemp release], frcTemp = nil;
    [request release], request = nil;

    if ([[_frc fetchedObjects] count] == 0) {
        //<#statements#>
    }

    return _frc;
}

但是它仍然按名称排序。我插入了一个“我在这里”。比较器块中的日志行 & 没有出现在我的日志中,导致我认为比较器甚至没有被执行。

干杯和 TIA,佩德罗 :)

【问题讨论】:

标签: objective-c ios sorting core-data


【解决方案1】:

NSSortDescriptor 不接受瞬态属性。但是有一个解决方法。

在 NSFetchedResultsController 中

将“sectionNameKeyPath”设置为您的过滤器,并将 NSSortDescriptor 保留为您的核心数据中的真实列。 所以你的代码是:

NSFetchedResultsController *fetcher = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                                  managedObjectContext:context
                                                                    sectionNameKeyPath:@"sortname" 
                                                                             cacheName:nil];

【讨论】:

  • 除非我弄错了,否则这不适用于未分组的列表,并导致分组列表中有很多 1 项组。
【解决方案2】:

您可能希望将排序描述符与块或选择器(函数)一起使用,例如

+[NSSortDescriptor sortDescriptorWithKey:ascending:comparator:]

使用块或选择器,您可以根据需要创建复杂和自定义的排序。

您还可以在同一个获取请求中使用多个排序,只需记住排序是按数组顺序计算的。

【讨论】:

  • 我已经编辑了这个问题,以包括我尝试实现这一点的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-09
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
相关资源
最近更新 更多