Swift - 通过成员数组的 属性 过滤数组的谓词
Swift - Predicate to filter an array by a property of member array
我需要过滤出一个 MyClass3 对象数组。 MyClass2 对象的数组是 MyClass3 对象的成员(请参考下面的代码)。 MyClass2 对象有一个 id。我手边有一个 idArray。我需要过滤掉那些 MyClass3 对象,其中 idArray 中的所有 id 都存在于其 [MyClass2] 成员中。
class MyClass2 : NSObject {
var uid: Int = 0
init(uid : Int) {
self.uid = uid
}
}
class MyClass3 : NSObject {
var arr: [MyClass2]
init(units: [MyClass2]) {
arr = units
}
}
var units1 = [MyClass2(uid: 1),MyClass2(uid: 2), MyClass2(uid: 3), MyClass2(uid: 4), MyClass2(uid: 5)]
var units2 = [MyClass2(uid: 4),MyClass2(uid: 5), MyClass2(uid: 6)]
var units3 = [MyClass2(uid: 3),MyClass2(uid: 5), MyClass2(uid: 7), MyClass2(uid: 1)]
var ids = [1,5]
var available3: [MyClass3] = [MyClass3(units: units1), MyClass3(units: units2), MyClass3(units: units3)]
var filtered3: [MyClass3] = []
let searchPredicate: NSPredicate = NSPredicate(format: " ANY arr.uid IN \(ids)") // needed predicate
print(searchPredicate.predicateFormat)
filtered3 = (available3 as NSArray).filteredArrayUsingPredicate(searchPredicate) as! [MyClass3]
要求的答案是我们需要过滤后的数组中的 MyClass3(units: units1) 和 MyClass3(units: units3)。
这行不通。有人可以为此目的建议谓词格式吗
你可以使用执行交集操作而不是 NSPredicate:
参考下面 link 这个
Set operations (union, intersection) on Swift array?
在谓词格式字符串中使用字符串插值从来都不是好事
主意。谓词的正确形式是
let searchPredicate = NSPredicate(format: "ANY arr.uid IN %@", ids)
然而,它会检查给定列表中是否有 any 的 uid。
要检查 all uid 是否在给定列表中,以下谓词
应该工作:
let searchPredicate = NSPredicate(format: "SUBQUERY(arr.uid, $x, $x IN %@).@count = %d", ids, ids.count)
在 "pure" Swift 3 中没有谓词也可以实现相同的效果
filtered3 = available3.filter { [=12=].arr.filter { ids.contains([=12=].uid) }.count == ids.count }
或
filtered3 = available3.filter { Set(ids).isSubset(of: [=13=].arr.map { [=13=].uid }) }
您可以查看此 link 以获得很好的示例,但对于数组的过滤,您可以使用类似的东西:
filteredArray = wholeArray.filter{ !unwantedArray.contains([=10=])}
我需要过滤出一个 MyClass3 对象数组。 MyClass2 对象的数组是 MyClass3 对象的成员(请参考下面的代码)。 MyClass2 对象有一个 id。我手边有一个 idArray。我需要过滤掉那些 MyClass3 对象,其中 idArray 中的所有 id 都存在于其 [MyClass2] 成员中。
class MyClass2 : NSObject {
var uid: Int = 0
init(uid : Int) {
self.uid = uid
}
}
class MyClass3 : NSObject {
var arr: [MyClass2]
init(units: [MyClass2]) {
arr = units
}
}
var units1 = [MyClass2(uid: 1),MyClass2(uid: 2), MyClass2(uid: 3), MyClass2(uid: 4), MyClass2(uid: 5)]
var units2 = [MyClass2(uid: 4),MyClass2(uid: 5), MyClass2(uid: 6)]
var units3 = [MyClass2(uid: 3),MyClass2(uid: 5), MyClass2(uid: 7), MyClass2(uid: 1)]
var ids = [1,5]
var available3: [MyClass3] = [MyClass3(units: units1), MyClass3(units: units2), MyClass3(units: units3)]
var filtered3: [MyClass3] = []
let searchPredicate: NSPredicate = NSPredicate(format: " ANY arr.uid IN \(ids)") // needed predicate
print(searchPredicate.predicateFormat)
filtered3 = (available3 as NSArray).filteredArrayUsingPredicate(searchPredicate) as! [MyClass3]
要求的答案是我们需要过滤后的数组中的 MyClass3(units: units1) 和 MyClass3(units: units3)。
这行不通。有人可以为此目的建议谓词格式吗
你可以使用执行交集操作而不是 NSPredicate:
参考下面 link 这个
Set operations (union, intersection) on Swift array?
在谓词格式字符串中使用字符串插值从来都不是好事 主意。谓词的正确形式是
let searchPredicate = NSPredicate(format: "ANY arr.uid IN %@", ids)
然而,它会检查给定列表中是否有 any 的 uid。 要检查 all uid 是否在给定列表中,以下谓词 应该工作:
let searchPredicate = NSPredicate(format: "SUBQUERY(arr.uid, $x, $x IN %@).@count = %d", ids, ids.count)
在 "pure" Swift 3 中没有谓词也可以实现相同的效果
filtered3 = available3.filter { [=12=].arr.filter { ids.contains([=12=].uid) }.count == ids.count }
或
filtered3 = available3.filter { Set(ids).isSubset(of: [=13=].arr.map { [=13=].uid }) }
您可以查看此 link 以获得很好的示例,但对于数组的过滤,您可以使用类似的东西:
filteredArray = wholeArray.filter{ !unwantedArray.contains([=10=])}