5

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

3 Answers 3

10

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 }) }
Sign up to request clarification or add additional context in comments.

Comments

1

You can do using perform intersection operation instead of NSPredicate:

Refer below link for this

Set operations (union, intersection) on Swift array?

2 Comments

Am not able to do this directly as I have a custom array which contains another custom array which is to be filtered out using an idArray.
you can do using this operation but you need to do some logic for what you want in result .
0

You can check out this link for good examples but for filtering of arrays you can use something like :

filteredArray = wholeArray.filter{ !unwantedArray.contains($0)}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.