RealmSwift - is it possible to combined the results of a List property into a single Result<>

Never quite sure where to post this type of question these days but I will give it a go here…

The model is as follows (simplified example)

class Parent: Object {
   let id = ObjectId()
   let name: String = "some name"

   let children = List<Child>
}

class Child: Object {
   let id = ObjectId()
   let name: String = "some name"

}

How can I get all the parents children back as a since results set ? It seems odd to define the var all as a LazySequence<FlattenSequence<LazyMapSequence<Results<Parent>, List<Child>>.Elements>>

    extension Child {
    
       var all: Results<Child> {
          let parents = realm.objects(Parent.self)
    
          // Returns LazyMapSequence<Results<Parent>, List<Child>>
          let children = parents.map({$0.children})
    
          // Returns LazySequence<FlattenSequence<LazyMapSequence<Results<Parent>, List<Child>>.Elements>>
          let all = children.joined()
    
          return all
       }
    }

The only other way I can think of is to add a property ‘parent’ to the ‘Child’ objects and then query the realm for all children whose ‘parent’ is IN the parents Result set.

extension Child {
        
           var all: Results<Child> {
              let parents = realm.objects(Parent.self)
        
              // Returns LazyMapSequence<Results<Parent>, List<Child>>
              let children = realm.objects(Child.self).filter("parent IN %@", parents)
        
              return children
           }
        }

First question is why do you want to get the children back as a Results? What will you being doing with them?

Then, let’s fix the objects and include LinkingObjects which generates a path back to the parent

class Parent: Object {
   @objc dynamic var id = ObjectId()
   @objc dynamic var name: String = ""

   let children = List<Child>()
}

class Child: Object {
   @objc dynamic var id = ObjectId()
   @objc dynamic var name: String = ""

    let linkingParent = LinkingObjects(fromType: Parent.self, property: "children")
}

Suppose we have a parent with the name Jay and we we to get all Jay’s kids as a Results object

let jayChildren = realm.objects(Child.self).filter("ANY linkingParent.name == 'Jay'")
for child in jayChildren {
   print("  ", child.name)
}

That being said, getting anything by name is a bit vacuous as there could be a lot of ‘Jay’ in the Parent class. So, if you get the certain parent object, you can match it that way which is guaranteeed to only get that parents children.

let jayChildren = realm.objects(Child. self ).filter("ANY linkingParent == %@", jayObject)

We have extensions to the parent that provide filtered sets of Results based on some rules unique to each Parent.

So simply getting the child objects directly for each Parent misses out on any of the parent specific filters.

Which gets me thinking that perhaps we should look at using the Parent to just generate the NSPredicates to filter the Child objects - each parent can generate its own compound predicate and in theory we can then just query the Child objects using this filter.

It just seems simpler to be able to use the following code structure

let parents = realm.objects(Parent.self).filter(some filter)

let allSomeChildren = parents.map({$0.someChildren(params)}).joined()

Rather than this

// Get array of predicates
let allSomeChildrenPredicates = parents.map({$0.someChildrenPredicate(params)}).reduce([], +)

let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: allSomeChildrenPredicates)

let allSomeChildren = realm.objects(Child.self).filter(predicate)

Not sure if there are any limits on the use of NSPredicate in this type of situation.

A couple of things. Your question asked

And my answer above is a solution. However, if there are additional criteria, it would be good to include them in the question so any answers can address that. It’s good to know that:

But what, specifically, does that mean? I think we may be able to craft a more helpful answer but understanding the use case would help.

Then, and this is very important - using Swift filtering and mapping on Realm objects totally disconnects them from Realm - so this code casts the realm objects to an array, all stored in memory

let allSomeChildren = parents.map

and a large dataset can overwhelm the device because all of the objects are loaded into memory, which overrides the natural lazy-loading aspect of Realm. Those objects also are disconnected and will no longer live update or even really be Realm objects.

It may be ok in this use case but just something to keep in mind.