Realm Swift - Find by IDs

Viewed 2057

I need to query Realm objects using a list of ids, id being the object's primary key. I have tried the following:

// Query a list of Dogs by their _ids
let doggoIds = ["1", "2", "3", "1", "2"]
realm.objects(Dog.self).filter("_id IN %@", doggoIds)
// Result: [Dog1, Dog2, Dog3]

The list of ids contains duplicates, but as you can see the result is a list of unique Dog objects.

I'm wondering if anyone can think of a different way to write this query so that we get a nice Results<Dog> collection from that list of ids that includes duplicates. Thanks!

2 Answers

Realm results contain unique objects so the easiest solution is to query for each dog and add the result to an array. CompactMap does this well as it filters out nil.

let listOfDogsToFind = ["Fido", "Dino", "Sport", "Fido", "Cupid"]

let dogArray = listOfDogsToFind.compactMap { dogName -> DogClass? in
    if let result = realm.objects(DogClass.self).filter("dog_name == %@", dogName).first {
        return result
    }
    return nil
}

for dog in dogArray {
    print("dog name: \(dog.dog_name)")
}

assume Cupid doesn't exist, here's the output

dog name: Fido
dog name: Dino
dog name: Sport
dog name: Fido

Realm.objects().filter returns a list of "live", managed objects. It will not return duplicates because there is only one object matching the primary key. In order to accomplish what you want, you'll need to create an 'unmanaged' duplicate of each object and make your own array of those unmanaged objects map each returned instance into your own array.

A la:

let doggoIds = [1, 2, 3, 1, 2]
    for managedMuttId in doggoIds {
        if let managedMutt = realm.object(ofType: Dog.self, forPrimaryKey: managedMuttId) {
            // unmanaged.append(Dog(value: managedMutt))
            duplicateList.append(managedMutt)
        }
    }
Related