Search code examples
swiftrealm

Querying for a matching array property in Realm


Consider the following, using Realm Swift:

class Shelf : Object {
    let products = List<Product>()
}

and

class Product : Object {
    let string: String = ""
    let Shelves = LinkingObjects(fromType: Shelf.self, property: "products")
}

Now the question is, is it possible to perform a query like:

"What are all the shelves that match EXACTLY a specific product list?" (no more, no less).

I could not find a way to compare an array.

EDIT: If I try doing this:

let results = realm.objects(Shelf.self).filter("%@ == products",products)

I get the error:

Invalid predicate: 
Key paths that include an array property must use aggregate operations

Thank you.


Solution

  • Each Realm model class inheriting from Object conforms to the Equatable protocol by default due to the fact that Object inherits from NSObject, which conforms to Equatable. If the elements of a List conform to the Equatable protocol, the List itself conforms to it as well.

    Hence, you should be able to compare List<Product> instances by using the == function and you can also directly compare Shelf objects.

    However, be aware that Realm overrides the == function, see Realm object's Equatable is implementation.

    If you want a custom comparison, you can override the == function yourself.

    Edit: I don't think this can be done using Realms filter method. However, if you don't mind getting an Array back as a result and not a Result collection, the below method can help you.

    let searchedProducts = List([product1, product2, product3])  //these are Product instances
    let results = Array(realm.objects(Shelf.self)).filter{
        if $0.products.count != searchedProducts.count {
            return false
        }
        for product in $0.products {
            if searchedProducts.index(of: product) == nil {
                return false
            }
        }
        return true
    }
    

    The above code has been tested in Playground with a similar class and returned correct results.