I need to filter out an array of MyClass3 Objects. An array of MyClass2 Objects is a member of MyClass3 object(Please refer to code below). MyClass2 object has an id. I have an idArray at hand. I need to filter out those MyClass3 objects in which all ids in idArray are present in its [MyClass2] member.
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]
The required answer is that we need MyClass3(units: units1) and MyClass3(units: units3) in the filtered Array.
This is not working out. Can someone suggest a predicate format for this purpose
A definition of logical conditions for constraining a search for a fetch or for in-memory filtering.
To filter strings in a Swift String Array based on length, call filter() method on this String Array, and pass the condition prepared with the string length as argument to the filter() method. filter() method returns an array with only those elements that satisfy the given predicate/condition.
If you create an array, a set, or a dictionary, and assign it to a variable, the collection that's created will be mutable. This means that you can change (or mutate) the collection after it's created by adding, removing, or changing items in the collection.
Using string interpolation in predicate format strings is never a good idea. The correct form of your predicate would be
let searchPredicate = NSPredicate(format: "ANY arr.uid IN %@", ids)
However that checks if any of the uids is in the given list. To check if all uids are in the given list, the following predicate should work:
let searchPredicate = NSPredicate(format: "SUBQUERY(arr.uid, $x, $x IN %@).@count = %d", ids, ids.count)
The same can be achieved without predicates in "pure" Swift 3 as
filtered3 = available3.filter { $0.arr.filter { ids.contains($0.uid) }.count == ids.count }
or
filtered3 = available3.filter { Set(ids).isSubset(of: $0.arr.map { $0.uid }) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With