iOS SDK详解之NSPredicate(Swift)
前言:谓词在集合过滤以及CoreData中有着广泛的应用。本文以Playground上的Swift代码为例,讲解如何使用NSPredicate。
准备工作
先在Playground上建立一个数组,为后文的谓词过滤做准备.这里我们充血了Description属性来为提供更加明显的输出。
import UIKit
class Person:NSObject {
var name:String
var age:Int
init(name:String,age:Int) {
self.name = name
self.age = age
super.init()
}
override var description:String{
return name:(self.name) age:(self.age)
}
}
let persons = NSMutableArray()
persons.addObject(Person(name: Jack Tomphon, age: 23))
persons.addObject(Person(name: Mikle Steven, age: 25))
persons.addObject(Person(name: Tacmk, age: 24))
从一个例子开始
let pridicateByAge = NSPredicate(format: age == 24)
let pridicateByAge2 = NSPredicate(format: age == %@,NSNumber(int: 24))
let pridicateByAge3 = NSPredicate(format: %K == %@,age,NSNumber(int: 24))
let pridicateByAge4 = NSPredicate (format: age == $age)
let result = persons.filteredArrayUsingPredicate(pridicateByAge)
let resule2 = persons.filteredArrayUsingPredicate(pridicateByAge2)
let result3 = persons.filteredArrayUsingPredicate(pridicateByAge3)
let result4 = persons.filteredArrayUsingPredicate(pridicateByAge4.predicateWithSubstitutionVariables([age:NSNumber(int: 24)]))
然后,再看看Playgound给出的动态结果
可以看到,以上四种方式的效果是一样的,由此我们接着讲解谓词的语法结构。
语法结构
使用%@
对应数字,字符串,日期的替代值 使用
%K
对应要比较的属性,也就是KVC中的key 使用
$变量名
来表示通配的变量,然后
predicateWithSubstitutionVariables
来决定具体的变量值
基本比较
比较符号,都是针对于左边表达式和右边表达式
1. > 大于
2. > =大于等于
3. < 小于
4. <=小于等于
5. ==等于
6. != 或者<> 不等于
7. BETWEEN 介于两者之间,包括上下限
举个例子
let pridivateByAge5 = NSPredicate(format: age BETWEEN { %@ , %@ }, NSNumber(int: 24),NSNumber(int: 25))
let result5 = persons.filteredArrayUsingPredicate(pridivateByAge5)
就是过滤24 <=age<=25
所以,可以看到Playground给出的结果是
[name:Mikle Steven age:25, name:Tacmk age:24]
复合比较
&& 或者AND 逻辑与 || 或者 OR 逻辑或 !或者NOT 逻辑非较为简单,这里不举例子了
字符串比较
BEGINSWITH 左边表达式以右边表达式开头 CONTAINS 左边表达式包含右边表达式 ENDSWITH 左边表达式以右边表达式结尾 LIKE 左边表达式和右边表达式相似(简单的正则表达式匹配,?匹配一个字符,*匹配0个或者多个字符) MATCHES 可以实现较为复杂的曾则表达式匹配 用方括号加cd来不区分大小写和变音符号 IN 左边的表达式在右边的集合里匹配以Ja开头
let pridivateByName1 = NSPredicate(format: name BEGINSWITH %@,Ja)
let result6 = persons.filteredArrayUsingPredicate(pridivateByName1)
println(result6)
名字里包含ac,不区分大小写,并且年龄大于等于24
let pridivateByName2 = NSPredicate(format: name CONTAINS %@ && age >= %@, ac,NSNumber(int: 24))
let result7 = persons.filteredArrayUsingPredicate(pridivateByName2)
println(result7)
复合正则表达式T[a-z]*k
let privatedivateByName3 = NSPredicate(format: name MATCHES 'T[a-z]*k')
let result8 = persons.filteredArrayUsingPredicate(privatedivateByName3)
名字是两者中的一个
let privatedivateByName4 = NSPredicate(format: name IN {'Tacmk','Jack Tomphon'})
let result9 = persons.filteredArrayUsingPredicate(privatedivateByName4)
基于Block的谓词
注意:基于Blcok的谓词不能用在CoreData的数据过滤上。基于Block能够灵活的定制谓词。
简单的Block定义age >24
let blockPredicate = NSPredicate { (person: AnyObject!, [NSObject : AnyObject]!) -> Bool in
var result = false
if let castResult = person as? Person{
if castResult.age > 24{
result = true
}
}
return result
}
let result10 = persons.filteredArrayUsingPredicate(blockPredicate)