【问题标题】:fetching objects from core data not in a set从不在集合中的核心数据中获取对象
【发布时间】:2011-09-05 03:13:24
【问题描述】:

我正在尝试从不在给定集中的核心数据中获取对象,但我无法让它工作。

例如,假设我们有一个名为 User 的核心数据实体,它具有一些属性,例如 userName、familyName、givenName 和 active。给定一个代表一组用户名的字符串数组,我们可以轻松获取与该用户名列表对应的所有用户:

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User"
                                          inManagedObjectContext:moc];
[request setEntity:entity];

NSArray *userNames = [NSArray arrayWithObjects:@"user1", @"user2", @"user3", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userName IN %@", userNames];
[request setPredicate:predicate];
NSArray *users = [moc executeFetchRequest:request error:nil];

但是,我想获取该集合的补集,即,我想要核心数据中没有在 userNames 数组中指定的用户名的所有用户。有谁知道如何解决这个问题?我认为在谓词(i.e., "userName NOT IN %@") 中添加"NOT" 会很简单,但是Xcode 抛出一个异常,说无法解析谓词格式。我还尝试使用可用于获取请求的谓词构建器,但没有成功。该文档也不是特别有用。建议?注释?感谢您的所有帮助:)

【问题讨论】:

    标签: iphone objective-c core-data nspredicate


    【解决方案1】:

    为了找到不在您的数组中的对象,您所要做的就是这样:

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (userName IN %@)", userNames];
    

    这应该返回所有对象的请求,而不是您指定的对象

    【讨论】:

    • 够简单...谢谢,slev。
    • 太棒了。我以为它不起作用。但那是因为我数组中的数据来自另一个字段。谢谢。简单有效。
    • 注意:这不适用于 NSNumber 变量,这可能是有道理的,但如果您将枚举包装在 NSNumber 中,那就太可惜了。在这种情况下,请使用[NSPredicate predicateWithFormat:@"NOT (enumWrapper IN {%d, %d})", enum1, enum2]
    • 不适合我.. :( 虽然,[NSPredicate predicateWithFormat:@"userName IN %@", userNames] 工作得很好
    【解决方案2】:

    我不擅长core data/objective-c,但是谓词应该像下面的语句;

    [predicateFormat appendFormat:@"not (some_field_name in {'A','B','B','C'})"];
    

    一个例子:

    NSMutableString * mutableStr = [[NSMutableString alloc] init];
    
    //prepare filter statement
    for (SomeEntity * e in self.someArray) {
        [mutableStr appendFormat:@"'%@',", e.key];
    }
    
    //excluded objects exist
    if (![mutableStr isEqual:@""])
    {
        //remove last comma from mutable string
        mutableStr = [[mutableStr substringToIndex:mutableStr.length-1] copy];
    
        [predicateFormat appendFormat:@"not (key in {%@})", mutableStr];
    }
    
    //...
    //use this predicate in NSFetchRequest
    //fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateFormat];
    //...   
    

    【讨论】:

      【解决方案3】:

      这是另一个有用的示例,展示了如何获取字符串列表,并过滤掉任何不以字母 A-Z 开头的字符串:

      NSArray* listOfCompanies = [NSArray arrayWithObjects:@"123 Hello", @"-30'c in Norway", @"ABC Ltd", @"British Rail", @"Daily Mail" @"Zylophones Inc.", nil];
      
      NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF MATCHES[c] '^[A-Za-z].*')"];
      
      NSArray *filteredList = [listOfCompanies filteredArrayUsingPredicate:bPredicate];
      
      for (NSString* oneCompany in filteredList)
          NSLog(@"%@", oneCompany);
      

      当我使用 A-Z 索引填充 UITableView 时,我使用这种 NSPredicate,并且想要一个“其他所有”部分用于不以字母开头的项目。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-08
        • 1970-01-01
        • 2023-04-11
        • 1970-01-01
        相关资源
        最近更新 更多