Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

kotlin map objects and filter from inner list

I’m making a DB request and getting back a list of objects. Within this list of objects is another list, which I want to filter on. After filtering, I then want to map the remaining objects to my domain model.

So I have my Database model:

data class TaskDatabaseModel(

    @PrimaryKey
    @ColumnInfo(name = "id")
    var id: String,

    @ColumnInfo(name = "task_categories")
    val categories: List<TaskCategory>,

    //Other fields
)

And my domain model:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

@Parcelize
data class Task(
    val id: String,
    val taskCategories: List<TaskCategory> = listOf(TaskCategory(TaskCategoryType.GENERAL)),
    //Other fields
) : Parcelable

TaskCategory:

@Parcelize
data class TaskCategory(val type: TaskCategoryType, val id: String? = null) : Parcelable

My function to get the list:

override fun getTasks(taskId: String): Flowable<List<Task>> {
    return db.getTasksDao().getAllTasks()
        .map { taskList ->
            taskList.map { listTaskDbModel ->
                listTaskDbModel.mapToDomainModel(cache.getCurrentUserId())
            }
        }
        .filter { taskList ->
            taskList.find { it.taskCategories.find { category -> category.id == taskId } != null } != null
        }
}

The filter code returns all items and doesn’t filter.

How do I change it so I only return the objects that have the required id in the categories list? Would it be easier to do it on the DB query? The list is stored as JSON.

Thanks

>Solution :

I believe you are applying the filter on the wrong object. You’re applying it on the Flowable rather than on taskList. This means that if at least one task matches your condition, you’ll keep all tasks. The below should be correct if I understand your intent:

override fun getTasks(taskId: String): Flowable<List<Task>> {
    return db.getTasksDao().getAllTasks()
        .map { taskList ->
            taskList.map { listTaskDbModel ->
                listTaskDbModel.mapToDomainModel(cache.getCurrentUserId())
            }
        }
        .map { taskList ->
            taskList.filter { it.taskCategories.any { category -> category.id == taskId } }
        }
}

More generally, if you can do a filter in the DB query, it’s likely faster… You may get a lot of data back if you don’t filter it at the source, which will cause more data to need to be sent through the network, parsed and loaded in memory. If this is a lot, it will also cause more work for the garbage collector. As a rule of thumb, I’d try to do most of the filtering at the DB level unless it’s hard to do so or if the data is tiny and expected to remain so.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading