Ryan
Ryan

Reputation: 1019

How to filter using NSPredicate based on if the to many relationship set contains a specific value

I have to two entities. One entity Person, the other Message. For every one Person, there are many messages (so there is a one to many relationship). I need to populate my tableView with Persons, but only Persons which have a set of messages that has at least one message with the attribute sent equalling success.

If what I said is not clear, here is basically what I want:

(obviously this does not compile, I completely made it up for the sake of the question) NSPredicate(Person.messages.contains (sent == "success")

Edit: Forgot to mention that I'm using Core - Data, not just a regular array. I need that NSPredicate for fetched results controller.

Upvotes: 1

Views: 1170

Answers (3)

Martin R
Martin R

Reputation: 539965

"ANY" can be used with a to-many relationship to find the objects for which at least one of the related objects satisfies a condition. In your case:

 NSPredicate(format: "ANY messages.sent == %@", "success")

Upvotes: 2

Marat Ibragimov
Marat Ibragimov

Reputation: 1084

Thats because your Persons Array should be NSArray , NSPredicates works only with Foundation objects not swift types.in Swift arrays you have filter method that you can call and pass it the filtering closure.

Upvotes: 0

Thomas G.
Thomas G.

Reputation: 1003

You could use filter function on swift array like so:

struct Person {

    var name: String?
    var meessages = [Message]()
}


struct Message {

    var sent: Bool = false
}


let arr: [Person] = [
    Person(name: "person1", meessages: [Message(sent: true), Message(sent: false)]),
    Person(name: "person2", meessages: [Message(sent: false), Message(sent: false)]),
    Person(name: "person2", meessages: [Message(sent: true), Message(sent: true)])
]

let filtered = arr.filter({ ($0.meessages.filter({ $0.sent == true })).count > 0 })

Upvotes: 0

Related Questions