HJo
HJo

Reputation: 2205

Why can't I get the index of a filtered realm List?

I'm trying to find the index of an item in a List<> object after the item has been appended to it, so that I can insert into a tableview.

The tableview is sectioned with .filters so I have to apply the filter before looking for the indexPath. However, the filter appears to break the indexOf functionality.

I noticed that the function .map has the same effect.

import UIKit
import RealmSwift

class Model: Object {
    @objc dynamic var title: String = ""
    let items = List<Model>()
}

class ViewController: UIViewController {

    var models: Results<Model>?
    var parentModel: Model?
    var items = List<Model>()
    let realm = try! Realm()

    override func viewDidLoad() {
        super.viewDidLoad()

        if !UserDefaults.standard.bool(forKey: "IsNotFirstTime") {
            populateRealm()
            UserDefaults.standard.set(true, forKey: "IsNotFirstTime")
        }

        models = realm.objects(Model.self)

        parentModel = models!.first
        items = parentModel!.items

        let child = Model()
        child.title = "Child"

        try! realm.write {
            parentModel!.items.append(child)
        }

        print(items.index(of: child)) // prints correct value
        print(items.filter({ $0.title == "Child" }).index(of: child)) // prints nil
    }

    func populateRealm() {
        let parent = Model()
        parent.title = "Parent"
        try! realm.write {
            realm.add(parent)
        }
    }
}

The first print finds the object, but the second print doesn't, despite the mapping having no overall effect.

The strange thing is that the object IS in the filtered list, doing:

print(items.filter({ $0.title == "Child" }).first

Returns the object, so it is there.

Edit

On further inspection, it looks like it's not the filter but the conversion of array type that breaks the functionality, converting to array without a filter does the same thing.

print(Array(items).index(of: child)) // prints nil

Upvotes: 0

Views: 1346

Answers (2)

HJo
HJo

Reputation: 2205

I figured out the solution. The filter syntax I used .filter({ $0.title == "Child" }) isn't the Realm filter, and converts the List to a LazyFilterCollection<List<Model>>, which doesn't seem to be compatible with searching for the index of a realm object.

The fix was to use the format .filter("title == %@", "Child"), which returns a realm Results object.

Upvotes: 0

A.Munzer
A.Munzer

Reputation: 1990

When you want to use mapping you should add an attributes to map your objects according to it for example

    print(items.map({ $0.id }).index(of: child.id))

if you use it on this way it will return what you expected

Upvotes: 2

Related Questions