iOS 谓词(NSPredicate)

2023-05-16

文档定义

NSPredicate:A definition of logical conditions used to constrain a search either for a fetch or for in-memory filtering.(逻辑条件的定义,用于限制对访存或内存中过滤的搜索。)

谓词代表逻辑条件,可用于过滤对象集合。 虽然直接从NSComparisonPredicate,NSCompoundPredicate和NSExpression的实例创建谓词是很常见的,但是您通常会根据由NSPredicate上的类方法解析的格式字符串来创建谓词。 谓词格式字符串的示例包括:
1. 简单比较,例如成绩==“ 7”或“ Shaffiq”这样的名字
2. 大小写不敏感的查找,例如名称contains [cd]“ itroen”
3. 逻辑运算,例如(名字,例如“ Mark”)或(姓氏,例如“ Adderley”)
4. 时间范围限制,例如{$ YESTERDAY,$ TOMORROW}之间的日期。
5. 关系条件,例如group.name之类的“ work *”
6. 聚合操作,例如@ sum.items.price <1000
有关完整的语法参考,请参阅《谓词编程指南》。

谓词的创建

谓词字符串解析器对空格不敏感,对关键字不区分大小写,并且支持嵌套的括号表达式。 它还支持printf样式的格式说明符(例如%x和%@)-请参阅格式化字符串对象。 变量用 表 示 ( 例 如 表示(例如 VARIABLE_NAME)-有关更多详细信息,请参见使用谓词模板创建谓词。
predicateFormat 后面的字符串如何设置可以查看 谓词格式字符串语法

解析器不执行任何语义类型检查。 它会尽力而为地创建合适的表达式,但是(尤其是在替换变量的情况下)可能会生成运行时错误。(确保format字符串是正确的,否则会运行时崩溃)

//初始化方法
public convenience init(format predicateFormat: String, _ args: CVarArg...)

例子:

//like[c]是不区分大小写
let pre = NSPredicate.init(format: "(lastName like[c] %@) AND (birthday > %@)", "abc",NSNumber.init(value: 10))
let result =  pre.evaluate(with: ["lastName":"abc","birthday":11])
print(result)// true

出来通过固定字符串创建谓词以外,还支持 字符串常量,变量和通配符创建谓词
例子:

let pre = NSPredicate.init(format: "lastName like[c] 'S*'")
let result = pre.evaluate(with: ["lastName":"sss"])
print(result)// true

var prefix = "prefix"
var suffix = "suffix"
let pre = NSPredicate.init(format: "lastName like[c] %@", "\(prefix + "*" + suffix)")
let result = pre.evaluate(with: ["lastName":"prefixxxxxxsuffix"])
print(result)// true

/// 数字,bool 类型需要用NSNumberv包裹
let pre = NSPredicate.init(format: "age > %@",NSNumber.init(value: 20))
let result = pre.evaluate(with: ["age":30])
print(result)// true

如果要指定动态属性名称,请在格式字符串中使用%K,如以下片段所示。
由于使用%@将字符串变量替换为格式字符串时,字符串变量用引号引起来,因此您不能使用%@指定动态属性名称,如以下示例所示

var key = "name"
var value = "abc"
let pre = NSPredicate.init(format: "%@ like %@",key,value)
let result = pre.evaluate(with: ["name":"abc"])
print(result)// false

上面这种情况下,谓词格式字符串的值为“name”(注意是带双引号的)
也就是format字符串是 “ “name” like xx 所以匹配结果是false
将key 部分的%@ 换成%K 就能正确匹配

var key = "name"
var value = "abc"
let pre = NSPredicate.init(format: "%K like %@",key,value)
let result = pre.evaluate(with: ["name":"abc"])
print(result)// true

NSComparisonPredicate和NSCompoundPredicate提供方便的方法,使您可以轻松地分别创建复合谓词和比较谓词。 NSComparisonPredicate提供了许多运算符,从简单的相等性测试到自定义函数。详系可以看Creating Predicates Directly in Code

谓词的使用

判断是否符合谓词 可以使用NSPredicate方法evaluateWithObject:并传入要对其评估谓词的对象。也可以将谓词与任何对象类一起使用,但是该类必须支持要在谓词中使用的键的键值编码(key-value coding)。

  1. 在数组中使用谓词
//filtered 是NSArray中的方法,swift中的Array没有这个方法,Array 可以使用filter(isIncluded: (String) throws -> Bool )
let  array = NSArray.init(array: ["Nick", "Ben", "Adam", "Melissa"])
let  pre = NSPredicate.init(format: "SELF beginswith[c] 'b'")
let result = array.filtered(using: pre)
print(result)//[Ben]
  1. Key-Paths 使用 谓词
//KVC的类必须继承自NSObject,变量并且用@objc修饰,否则直接报错
class Person:NSObject{
    @objc var age = 10
}
var person = Person()
let pre = NSPredicate.init(format: "age < %@",NSNumber(value: 20))
let result = pre.evaluate(with: person)
print(result)//true
  1. 筛选nil值
let arr = NSArray.init(array: [["name":"小明"],["name":"小红","age":20]])
let pre = NSPredicate.init(format: "age != nil")
let result = arr.filtered(using: pre)
print(result)
/*
[{
 age = 20;
 name = "\U5c0f\U7ea2";
}]
*/
  1. CoreData 使用谓词
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Employee"
        inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSNumber *salaryLimit = <#A number representing the limit#>;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"salary > %@", salaryLimit];
[request setPredicate:predicate];
NSError *error;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
  1. 使用正则表达式
let predicate =  NSPredicate(format: "SELF MATCHES %@" ,"\\d*")
let result = predicate.evaluate(with: "123456789")
print(result)//true

let  predicate = NSPredicate(format: "(name matches %@)&&(age matches %@)" ,"[a-z]*","\\d*")
let  result = predicate.evaluate(with: ["name":"abcd","age":"20"])
print(result)//true

谓词format

  1. 比较符号,都是针对于左边表达式和右边表达式

    • > 大于
    • > =大于等于
    • < 小于
    • <=小于等于
    • ==等于
    • != 或者<> 不等于
    • BETWEEN 介于两者之间,包括上下限
  2. 复合比较

    • && 或者AND 逻辑与
    • || 或者 OR 逻辑或
    • !或者NOT 逻辑非
  3. 字符串比较

    • BEGINSWITH 左边表达式以右边表达式开头
    • CONTAINS 左边表达式包含右边表达式
    • ENDSWITH 左边表达式以右边表达式结尾
    • LIKE 左边表达式和右边表达式相似(简单的正则表达式匹配,?匹配一个字符,*匹配0个或者多个字符)
    • MATCHES 可以实现较为复杂的曾则表达式匹配
    • 用方括号加cd来不区分大小写和变音符号
    • IN 左边的表达式在右边的集合里
    • UTI-CONFORMS-TO该运算符的左侧参数是一个表达式,其计算结果为您要匹配的通用类型标识符(UTI)。 右侧参数是一个表达式,其计算结果为UTI。 如果左侧表达式返回的UTI符合右侧表达式返回的UTI,则比较的结果为TRUE。有关哪些类型符合给定类型的信息,请参见《统一类型标识符参考》中的系统声明的统一类型标识符
    • UTI-EQUALS 该运算符的左侧参数是一个表达式,其计算结果为您要匹配的通用类型标识符(UTI)。 右侧参数是一个表达式,其计算结果为UTI。 如果左侧表达式返回的UTI等于右侧表达式返回的UTI,则比较结果为TRUE。
  4. 集合操作

    • ANY,SOME
      指定以下表达式中的任何元素。例如,任何child.age <18。
    • ALL
      指定以下表达式中的所有元素。例如,所有children.age <18。
    • NONE
      不指定以下表达式中的任何元素。例如,NONE children.age <18。这在逻辑上等效于NOT(ANY …)。
    • IN
      等效于SQL IN操作,左侧必须出现在右侧指定的集合中。
      例如,命名为IN {‘Ben’,‘Melissa’,‘Nick’}。集合可以是数组,集合或字典,如果是字典,则使用其值。
    • array[index]
      指定数组数组中指定索引处的元素。
    • array[FIRST]
      指定数组数组中的第一个元素。
    • array[LAST]
      指定数组数组中的最后一个元素。
    • array[SIZE]
      指定数组数组的大小。
  5. 文字操作
    单引号和双引号产生相同的结果,但它们不会彼此终止。 例如,“ abc”和“ abc”相同,而“a’b’c”等效于a,“ b”,c的以空格分隔的串联。

    • FALSE,NO
      逻辑错误。
    • TRUE ,YES
      逻辑上正确。
    • NULL,NIL
      空值。
    • SELF
      表示被评估的对象。
    • “text”
      字符串。
    • ‘text’
      字符串。
    • 逗号分隔的文字数组
      例如,{‘逗号’,‘分隔’,‘文字’,‘数组’}。
    • 标准整数和定点表示法
      例如1、27、2.71828、19.75。
    • 浮点数与指数
      例如9.2e-5。
    • 0x
      用于表示十六进制数字序列的前缀。
    • 0o
      用于表示八进制数字序列的前缀。
    • 0b
      用于表示二进制数字序列的前缀。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 谓词(NSPredicate) 的相关文章

随机推荐

  • CentOS7使用iptables开放特定端口

    CentOS7 默认使用firewalld防火墙 xff0c 如果想换回iptables防火墙 xff0c 可关闭firewalld并安装iptables 一 关闭firewall xff1a 关闭防火墙 systemctl stop fi
  • SDUT 加密术

    加密术 Time Limit 1000MS Memory limit 65536K 题目描述 加密技术是一种常用的安全保密手段 xff0c 利用加密技术可以把重要的数据变成经过加密变成乱码传送 xff0c 到达目的地后再利用解密手段还原 现
  • 【原创】Ubuntu Server 22.04 LTS 设置主机信息以及IP地址

    1 安装网络工具 xff0c 我们需要nmcli这个工具 span class token function apt get span span class token function install span y network man
  • 【PC微信探秘】把C#的DLL注入到微信中

    NET的DLL不能直接注入 xff0c 需要两步 xff1a 先把C 43 43 的DLL注入 xff0c 然后C 43 43 把 NET的DLL引入 xff1a span class token comment dllmain cpp 定
  • 「xrdp」- 使用 Windows 远程 Linux 主机 @20210130

    xrdp xrdp xff0c 是 RDP 协议的服务端实现 xff0c 基于 FreeRDP 和 rdesktop 的工作 xff0c xrdp 使用 RDP xff08 远程桌面协议 xff09 向用户呈现图形化界面 该项目提供一个功能
  • 使用 STM32CubeMx + VSCode 开发 STM32

    使用 STM32CubeMx 43 VSCode 开发 STM32 目的 1 使用 STM32CubeMX配置STM32开发板 xff0c 生成Makefile工程 2 使用 VSCode 开发并调试 环境及工具 1 STM32CubeMx
  • Rust 编程之道-类型系统

    类型系统 基本类型 一切皆表达式 xff0c 表达式皆有值 xff0c 值皆有类型 xff0c 所以一切皆类型 包括 xff1a 基本类型复合类型作用域返回值 Option xff1c T xff1e Result xff1c T xff0
  • 揭露网络电脑短视频营销号中的套路【完全】

    1 temp 骗局 这是存放缓存文件的文件夹 xff0c 位置在C Users 用户名 AppData Local Temp win 43 r输入 temp xff0c 我们点进去 xff0c 看到文件雀氏非常多 xff0c 但是再一看大小
  • 用中断实现流水灯

    include lt stm32f4xx h gt define GPIO Pin 6 0x0040 LED2 define GPIO Pin 7 0x0080 LED1 define PLL M 8 define PLL N 336 de
  • debian 无法使用apt-get解决办法

    刚装完debian xff0c 发现直接apt get是用不了的 xff0c 系统会提示你插入DVD xff0c 其实是源的配置问题 xff0c 只需要在apt的源里面修改下配置就可以了 打开apt源文件 sudo vi etc apt s
  • 蜗牛星际C单黑群晖加USB网卡做链路聚合

    黑群晖挂载USB网卡 一不小心入了群晖的坑 xff0c 然后就是不停的折腾 xff0c 入手一个蜗牛星际C单 xff0c 装好DS918 43 后 xff0c 家里有ASUS RT AC5300 xff0c 就想着搞个链路聚合 首先当然是去
  • CentOS 7 安装zoneminder

    这里写自定义目录标题 CentOS 7 安装zoneminder1 安装centos系统 xff0c 最小化安装2 配置源3 安装 zoneminder 以及环境4 关闭SELinux5 配置时区6 添加php网页支持7 安装配置数据库8
  • linux deploy linux 安装mariadb 无法启动解决办法

    这里写自定义目录标题 linux deploy linux 安装mariadb 无法启动解决办法 linux deploy linux 安装mariadb 无法启动解决办法 手头一个旧手机 xff0c 就想来折腾一番 xff0c 装到数据库
  • linux deploy 安装debian11 armhf中安装Zoneminder

    linux deploy 安装debian11 stable armhf 中安装Zoneminder 折腾了无数遍 xff0c 然后感觉也没啥用 安装linux deploy 手机获取root权限 安装debian xff08 armhf
  • OpenWRT 中创建docker Openwrt和其他宿主机中的docker容器通信

    这里写自定义目录标题 OpenWRT 中使用创建docker Openwrt和其他宿主机中的docker容器通信网络拓扑一 准备1 openwrt镜像 xff0c 2 安装pve 二 PVE配置1 网络配置2 创建docker networ
  • sublime text自定义clang format插件格式化C++代码

    本文内容为在windows平台上通过 sublime text开发自定义插件实现调用clang format对C C 43 43 代码进行格式化 需要安装LLVM xff0c 下载链接 xff1a https github com llvm
  • 四种方法实现UITableView的cell高度自动计算

    UITableview是iOS开发中使用最频繁的一个控件 xff0c 在实际开发中 xff0c 我们经常需要定制cell xff0c 让cell显示图片 文字等 由于cell包含的图片和文字是根据服务器返回的数据进行填充的 xff0c 这就
  • iOS贝塞尔曲线(UIBezierPath)的基本使用方法

    简介 UIBezierPath是对Core Graphics框架的一个封装 xff0c 使用UIBezierPath类我们可以画出圆形 xff08 弧线 xff09 或者多边形 xff08 比如 xff1a 矩形 xff09 等形状 xff
  • 手机termux免root安装kali:一步到位+图形界面

    1 工具 xff1a 安卓 xff08 包括鸿蒙 xff09 手机 WiFi 充足的电量 脑子 2 浏览器搜索termux xff0c vnc viewer xff0c 下载安装 3 对抗华为纯净模式需要一些操作 xff0c 先断网 xff
  • iOS 谓词(NSPredicate)

    文档定义 NSPredicate xff1a A definition of logical conditions used to constrain a search either for a fetch or for in memory