Currently I have a query that looks something like this:
override suspend fun getExternalTestsForProfile(profileKey: String, take: Int?): List<ExternalTestEntity> {
RealmDb.useRealm {
where(RealmExternalTest::class.java)
.sort(RealmExternalTestFields.CREATED_AT, Sort.DESCENDING)
.findAll()
I want to have functionality so that if take
is null, it will fetch all elements in the collection, but if an Int is supplied, it will take and map in that case only.
So my "desired" functionality is something like this:
override suspend fun getExternalTestsForProfile(profileKey: String, take: Int?): List<ExternalTestEntity> {
RealmDb.useRealm {
where(RealmExternalTest::class.java)
.sort(RealmExternalTestFields.CREATED_AT, Sort.DESCENDING)
.findAll()
if (take != null) {
.take(3)
} else {
// Do not apply a .take
}
.map { realmExternalTest -> realmExternalTest.toExternalTestEntity() }
I want the take to happen before the mapping because the mapping may be expensive, because it can have a ton of elements. So doing the expensive map operation only to take 3 elements is wasteful.
I considered overloading getExternalTestsForProfile
to have one with a take
and one without, but was hoping I could sort of combine it since the only real difference here is how many elements are mapped and returned out.
Thanks
CodePudding user response:
I don't know Realm, but looking at their API it looks like take
is not what you want here. You should instead limit() before you even call findAll()
, otherwise findAll()
would return all results.
Now to your actual question, whether you stick with take
or use limit
, you can use let
to perform this operation inline:
where(RealmExternalTest::class.java)
.sort(RealmExternalTestFields.CREATED_AT, Sort.DESCENDING)
.let {
if (take != null) it.limit(take) else it
}
.findAll()
Or you could extract this into a function for better readability:
private fun <E> RealmQuery<E>.maybeLimit(limit: Long?): RealmQuery<E> =
if (limit != null) limit(limit) else this