I have records with date field:
class SomeRealmObject: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var date: Date
... //some other properties
}
The goal is to calculate a count of records distinct by date ("distinct" should ignore time inside date).
If I already had a list of records I could work with them like usual elements of array:
let allObjects = getAll() //SomeRealmObject array
let dates = allObjects.map { $0.startOfDay() }.reduce([]) { partialResult, date in
partialResult.contains(date) ?
partialResult : partialResult + [date]
}
let result = dates.count
But is it possible to do the same with RealmSwift methods because I need only count of SomeRealmObject and don't need to get its inner data? There is for example distinct(by:) but it compares fields by their value and doesn't allow to specify additional conditions like startOfDay()
There are a few issues to overcome - first is that Realm functions don't allow us to 'dig' into dates - dates are the whole date, including the time.
Because of that, ignoring the time is not possible using Realm syntax. e.g. you can't do this
bummer.
Another non-working thought is to use a predicates (Realm supports some predicates) with a block to isolate the date components
But alas, Realm "Only supports compound, comparison, and constant predicates"
One solution (of many) is to consider what's being stored - a Date() object is actually a very specific timestamp, which includes the time. But that's not what your
distinctneeds - it needs the year, month and daySo, store the date components you want to compare as a separate property; possibly string or a date built with no time component
The
dateNoTimeproperty could be built by extracting the date components you want to distict on, create a new date object and store that; for exampleThere are a number of paths from there, one is to use a function or computed property that's backed by Realm properties to handle the date, so when setting the date on an object it writes out the actual timestamp version as well as the one used for distinct.
then you can use Realms
distinctto get the results*note this could also be done by loading the objects into an array and then use a Swift predicate to evaluate but that could cause memory issues and potentially be slower.