美文网首页
iOS 谓词(NSPredicate)

iOS 谓词(NSPredicate)

作者: lq_ios | 来源:发表于2019-12-17 15:05 被阅读0次

    文档定义

    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
        用于表示二进制数字序列的前缀。

    相关文章

      网友评论

          本文标题:iOS 谓词(NSPredicate)

          本文链接:https://www.haomeiwen.com/subject/qqcsnctx.html