Search code examples
iosiphoneswiftrealm

Swift Realm filter List property using an Array


I have this property in my Realm Object

 var tags = List<Tag>()
 "tags": [
        {
            "tagId": "80069",
            "tagName": "A"
        },
        {
            "tagId": "80070",
            "tagName": "B"
        },
        {
            "tagId": "80071",
            "tagName": "C"
        },
        {
            "tagId": "80073",
            "tagName": "D"
        }
    ]

I have a view controller that can filter out the tag.

So i have several buttons to toggle the filter. What I have done is i create an array for the filter for each of my button

var filteredList = [String]()

So, if i click Button A, it will append "A" to the filteredList array, and if I click Button B, it will append "B" to the filteredList array and so on

Currently this is my filter predicate

let realmFilteredList = self.realm.objects(MyDTO.self).filter("ANY tags.tagName IN %@", self.filteredList)

However, above predicate gives me wrong result, because if let's say i want to filter the tag with property "A,B,C,D" (exact ABCD), it will return me other tag that contain either A,B,C,or D.

How can I get the tag with exact "A,B,C,D" in my search predicate?

Any help given is highly appreciated.


Solution

  • You can't achieve your goals using predicate with Realm because Realm have a lot of limitations using Predicates and the missing ability to handle computed properties but you can use this way as a workarround

        let filterList = ["A","B"]
        let realmList = realmInstance?.objects(MyDTO.self)
        let filteredArray = Array(realmList!).filter({Array($0.tags).map({$0.tagName}).sorted().joined().contains(filterList.sorted().joined())})
    

    here Array($0.tags).map({$0.tagName}).sorted().joined() we get the tags array and convert it with map to an array of Strings then we sort that array of Strings (this will ensure that only matters the TAGS in the array not the order) and after that we convert that sorted array in a String by example your array of tags.tagName is ["B","A","C"] and after this you will get "ABC" as STRING

    after that we check if that STRING contains your filterList.sorted().joined() the same procedure that was explained before

    so if your filterList have ["B","C","A"] you will get "ABC"

    and the we check if "ABC" contains "ABC" if so then is included in final result