Home > Back-end >  Kotlin filter list by predicate
Kotlin filter list by predicate

Time:02-27

I am trying to filter a list based on a condition that a property inside the list is an enum type. But I get an error on the filter function. Can anyone tell me how to resolve this error and why it is happening?

Type inference failed. The value of the type parameter T should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.

My code is below:

data class Person(
    val name: String,
    val ageInDays: Int,
    val currentStatus: List<Status>,
)

data class Status(
    val name: String,
    val activity: Activity
)

enum class Activity {
    COOK,
    CLEAN,
    SLEEP,
}

fun main() {
    
    var build = listOf(
    Person("abc", 3655, listOf(
                                Status("abcProc1", Activity.COOK),
                                Status("abcProc2", Activity.CLEAN),
                                Status("abcProc2", Activity.SLEEP),
                              )
          ),
    Person("ghi", 500, listOf(
                                Status("ghiProc", Activity.COOK),
                                Status("ghiProc", Activity.SLEEP),
                              )
          ),
    Person("def", 1000,listOf(
                                Status("defProc", Activity.SLEEP)
                             )
          )
    )

println(build.filter { it.currentStatus.contains(Activity.CLEAN) })
    
}

CodePudding user response:

currentStatus is a List<Status>. The only type of object that could be in the list is a Status (or subtype thereof). So it doesn't make sense to call contains on the list with an argument that is not a Status. An Activity is not a subtype of Status.

Assuming you want to filter your list of Status to only include instances of Status for which the activity property is Activity.CLEAN, you would do it like:

build.filter { it.currentStatus.any { status -> status.activity == Activity.CLEAN } }

or slightly less efficient but possibly clearer logic:

build.filter { it.currentStatus.map(Status::activity).contains(Activity.CLEAN) }
  • Related