Home > OS >  Sort realm results using a property of an element in a list
Sort realm results using a property of an element in a list

Time:03-30

I have two realm classes... the first class Patient contains one or more of a second class Record, as the following:

class Patient: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var records: List<Record>

}

class Record: EmbeddedObject {
    @Persisted var date = Date()

    @Persisted(originProperty: "records") var patient: LinkingObjects<Patient>

}

I want to sort patients by the date of the last record, something like this:

patients = realm.objects(Patient.self).sorted(byKeyPath: "records.last.date", ascending: false)

Is this possible with realm and swift?

Thank you

CodePudding user response:

The objective is to sort patients by the latest date of a record in their in their list of records.

It can be done and there are several approaches. One option is, as patients records are being populated, to keep a separate property of the record with the latest date.

The patient object would look something like this

class Patient: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted private var records: List<Record>
    @Persisted var lastRecord: Record!

    func addRecord(withRecod: Record) {
        self.records.append(withRecord)
        let recordArray = Array(self.records)

        if withRecod != nil {
            let sortedRecords = recordArray.sorted { $0.date < $1.date }
            let lastRecord = sortedRecords.last!
            let rec = Record(value: lastRecord)
            self.lastRecord = rec
        }
    }
}

We added a function to populate the records list and made that list private so you are forced to use the addRecord function to populate the property.

The Array is needed as Realm doesn't sort in memory - so if the object is not yet persisted the records cannot be sorted, so an array is leveraged for that task.

Lastly, the array is sorted by date and then we make a COPY of the last record to store in the lastRecord property. Embedded objects are never persisted 'on their own' they can't be referenced in the same way other objects can, so a copy makes it work.

Then the sorting becomes easy

let patients = realm.objects(Patient.self).sorted(byKeyPath: "lastRecord.date")

Keeping in mind a updateRecord and a deleteRecord function may be in order to re-calculate the lastRecord upon those changes.

  • Related