How Query and Count entries in a Realm Database
They way you were computing the count required all Dog
objects to be loaded into memory which is really inefficient. This is why you were seeing such poor performance. You want to take advantage of Realm's lazy loading features. You may want to read up on that.
I would update your Dog
object by getting rid of your managed Person
property and replace it with LinkingObjects. If you store a Dog
in a Person.dogs
List, then realm will create a back link to the Person
for you. You will likely want to do the same thing with Cat
. That way you can set up some really powerful nested queries.
For convenience you can add a computed Person
property to index into the LinkingObjects
. Just know that you won't be able to use that property in any of your queries.
class Dog: Object {
@objc dynamic var name = ""
let persons = LinkingObjects(fromType: Person.self, property: "dogs")
var person: Person? { persons.first }
}
One way to compute the count is to query of all Person
objects and sum the count of dogs
for each Person
.
let count = realm.objects(Person.self).reduce(0) { result, person in
return result + person.dogs.count
}
Another options is to query for Dog
objects that have a corresponding Person
. If a Dog
is not in a Person.dogs
List, then it won't show up the query.
let realm = try! Realm()
let count = realm.objects(Dog.self).filter("persons.@count > 0").count
Either option is going to be much, much more efficient than what you had.
Hope this helps.
Realm Query to count number of unique entries
At a high level, if you have an array of Strings as shown in your question, and you want to get only unique Strings (no duplicates) you can cast it to a Set and you're done.
let nameArray = ["Adam", "Adam", "Ben", "Ben", "Ben", "Charlie", "Darren", "Darren"]
let nameSet = Set(nameArray)
print(nameSet)
and the output is
["Darren", "Charlie", "Ben", "Adam"]
If you would then like it ordered to be used as a dataSource, it can be cast back to an Array and sorted
let uniqueNameArray = Array(nameSet)
let orderedUniqueNameArray = uniqueNameArray.sorted()
print(orderedUniqueNameArray)
and the output
["Adam", "Ben", "Charlie", "Darren"]
(there are a lot of shortcuts that could be taken and you could probably make it a one-liner but I left it verbose for clarity)
EDIT
If you want to get Realm objects that are unique based on a certain property, you can use the .distinct function. Assume the Realm PersonClass as a name
property
let people = realm.objects(PersonClass.self)
let uniquePeopleByName = people.distinct(by: ["name"])
Realm - how to query for a List greater than 0 objects
I was so close!
let results = realm.objects(Person.self).filter("cats.@count > 0")
(needed the "@" before count
)
Related Topics
iOS - Send Image to Instagram - Documentinteraction
Openurl in Appdelegate Conversion Error Nsstring -> String (Swift & iOS8)
Why am I Getting an Error Regarding Bolts Framework and Facebooksdk When I'm Not Even Using Bolts
How to Send Msmessage in Messages Extension
Manage a Uipickerview from an External Class - Using Swift
How to Keep the Header Cell Moving with the Tableview Cells in Swift 2.0
Wkwebview Blank After 'Successful' Https Nsurlrequest
Programmatically Set Uipageviewcontroller Transition Style to Scroll
Swift Add Line Above to Control
Save Image with the Correct Orientation - Swift & Core Image
How to Convert This Opengl Pointer Math to Swift
iOS Swift 2 Record Video Avcapturesession
How to Get Label Name from Button
How to Add File Picker to the App on iOS 14+ and Lower
Diffabledatasource: Snapshot Doesn't Reload Headers & Footers
Do I Need to Wrap My Alamofire Calls Inside Dispatch_Async
How to Check If Device Orientation Is Landscape Left or Right in Swift