Home > other >  In Kotlin, can I have a conditional builder element on a collection?
In Kotlin, can I have a conditional builder element on a collection?

Time:07-20

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
  • Related