对数组中的字符串不区分大小写的NSPredicate?

时间:2010-01-06 22:58:56

标签: cocoa core-data nspredicate

我有一种情况,我想通过用户名密钥从我的核心数据存储中获取对象,但我希望比较不区分大小写。我的谓词就是:

username IN $usernames

然后我用一个字符串数组进行变量替换,这些字符串是我想要查找的用户名。它有效,但区分大小写。我想这样做,我想:

username IN[c] $usernames

不幸的是,这似乎不起作用。字符串比较仍必须以区分大小写的方式进行。 (我不会因为它是不受支持的查询而收到错误。)

有没有不同的方法来编写这个谓词,所以它以我需要的方式工作,或者我只是遗漏了一些明显的东西?

4 个答案:

答案 0 :(得分:10)

在对SQLite存储执行提取时,显然忽略了IN运算符上的case修饰符。 (您从问题中省略了商店类型。)

我建议对文档提交错误,以便记录此限制/行为。

我还建议在错误报告器中提交功能请求,以便将来考虑这一点。

与此同时,您必须从数据模型中提取获取请求并以编程方式构建它。您可以构建一个复合谓词OR谓词,为每个值执行不区分大小写的相等匹配(并测试它是否满足您的性能需求。)

请注意,如果您在10.6之前支持OS目标,则不支持==上的case修饰符,在这种情况下,还需要另一个替代解决方案。

答案 1 :(得分:1)

您可以尝试ANY $usernames LIKE[c] username之类的内容。我做过类似的事情,而不是变量替换,我只有一个像“persons.name”这样的关键路径,而且这个谓词对我有用。不确定它是否与变量有任何不同,而不是关键路径,但它值得一试。

答案 2 :(得分:1)

这是另一种解决方法,但需要您更改MOM。

让用户名成为一个完整的实体。创建用户名与您的其他实体之间的反向关系。

现在对于获取请求,将实体设置为“Username”,然后运行此谓词(假设“name”属性和“parent”属性):

   [NSPredicate predicateWithFormat:"(name like[c] %@) && (parent == %@)", theUserName, theParentObject]

这可能过度,但可以让您根据需要运行搜索。

答案 3 :(得分:-1)

虽然这个问题已经存在了几年,但我偶然发现了同样的问题,并解决了这个问题:

NSArray  *values = @[@"FOO", @"bar" ,@"lorem"];
NSString *predicate;

predicate = @"value LIKE[cd] '";
predicate = [predicate stringByAppendingString:
             [values componentsJoinedByString:
              @"' OR  value LIKE[cd] '"]];
predicate = [predicate stringByAppendingString:@"'"];

NSLog(@"%@",  predicate);
// Output:
// value LIKE[cd] 'FOO' OR  value LIKE[cd] 'bar' OR  value LIKE[cd] 'lorem'

这将从值列表中创建静态谓词表达式。也许这对某人有用。

更新2:

实际上,下面的更新解决方案似乎不适用于sqlite并生成

'NSInvalidArgumentException',
reason: 'unimplemented SQL generation for predicate : ... (bad LHS)'

我认为对于array / dict / set比较和IN,操作符左侧只允许使用键。

更新:

在对表达式和谓词进行一些研究之后,我发现了另一种方法,这看起来效果很好:

NSPredicate *predicate =
   [NSPredicate predicateWithFormat:
     @"lowercase(value) IN %@", values];

这使用函数表达式lowercase:来获取值的小写表示。剩下要做的就是确保values的所有条目都是小写的,并且您将能够使用不区分大小写的IN表达式。