在 NSPredicate 中比较整数和字符串

Posted

技术标签:

【中文标题】在 NSPredicate 中比较整数和字符串【英文标题】:Compare integer with string in NSPredicate 【发布时间】:2020-09-23 14:33:57 【问题描述】:

我在项目数组中有一系列锻炼程序(它们的代码在 Objective-C 上),在每个程序中我都有@property (nullable, nonatomic, copy) NSString *scheduleStr; 用于程序持续时间。此属性存储诸如 1 周2 周3 周 等值。我需要过滤所有大于 6 周的值。我正在尝试应用 NSPredicate:

predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 6"))

在此之后,我只收到长度为 6-9 周的程序,但不超过 10 周,但可以肯定的是,我在数据库中有几个长度等于 12 周的程序。 如果我试图应用这样的东西:

predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 10"))

我会收到几乎所有的节目。如何获取超过选定值的所有程序?

【问题讨论】:

您是在 Core Data 上使用谓词还是数组,它看起来像是一个数组,但您已使用 Core Data 标记了问题,因此不清楚。此外,您将谓词附加到数组中,那么您是否有多个同时使用的谓词(复合谓词)?我尝试使用自定义类和 NSArray 在操场上重现这一点,但谓词工作正常。 是的,这是核心数据。我正在请求获得一组合适的程序。 您是否单独测试了这个谓词而没有其他任何人的获取请求? 【参考方案1】:

问题在于,尽管您指定了integerValue,但在将谓词用作提取的一部分时,CoreData 将您的字符串视为字符串。在字符串方面,10 weeks 是“小于”6 weeks,因此它被排除在结果之外。

您应该存储数字(作为 Int)而不是存储字符串。然后添加文本“周”是您出于显示目的所做的事情。如果您存储的是数字而不是字符串,那么 CoreData 可以进行数值比较,并且您的谓词将按预期工作。

如果您真的不想这样做,可以使用一种解决方法和一种技巧。解决方法是过滤内存中的对象,而不是作为提取的一部分。然后,integerValue 将被正确解释,并且比较将是数字。

破解方法是强制 CoreData 将您的字符串视为数字,通过使用数字函数,例如 abs(假设您只有正数周数,取绝对值使值保持不变) :

predicates.append(NSPredicate(format: "abs:(scheduleStr) >= 6"))

【讨论】:

很遗憾,我无法更改保存信息的格式,所以感谢您解释问题的原因和破解。 @Maxvale:另一个“hack”是使用localizedStandardCompare作为比较函数,例如***.com/a/30554868/1187415。【参考方案2】:

要在您的情况下获取字符串中的整数部分,您可以查看以下内容:

假设元素就是你的字符串

let component = element.components(separatedBy: .letters) // this will give you the non letter values 
let integerValues = component.filter( $0 != "" ) 
print(integerValues[0]) // As first value in your input string is an integer

这将为您提供可用于过滤数组的字符串的整数部分。

【讨论】:

以上是关于在 NSPredicate 中比较整数和字符串的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate 与 64 位整数?

在保存到核心数据之前将字符串与 NSPredicate 进行比较

NSPredicate 对一个查询字符串进行多重比较

NSPredicate 谓词

正则表达式和NSPredicate

常用的正则表达式