Kotlin - 来自两个集合的过滤器/映射



是否可以根据所需的条件匹配来过滤和映射两个集合,如下所示:

fun main(args: Array<String>) {
val selectedDates = listOf("2018-08-12", "2018-08-13", "2018-08-14")
val expenses = listOf(Expense("Food", "2018-08-12"),
Expense("Transportation", "2018-08-15"),
Expense("Misc.", "2018-08-13"),
Expense("Uber", "2018-08-12"),
Expense("Clothing", "2018-08-16"))
val listOfExpensesInSelectedDate = mutableListOf<Expense>()
for (date in selectedDates){
listOfExpensesInSelectedDate.addAll(expenses.filter { it.date==date })
}
println(listOfExpensesInSelectedDate)
}
data class Expense(
val expense:String,
val date: String
)

提供上面给定的代码,我正在尝试返回与另一个字符串列表中的日期匹配的费用列表。 在上面的示例中,我同时使用了循环和过滤器函数来获得所需的结果。 但是,是否可以避免 for 循环并在一行代码中过滤和映射两个集合?

您可以使用in来过滤:

val listOfExpensesInSelectedDate = expenses.filter { it.date in selectedDates }

编辑:自从热键发布了有关最佳解决方案的评论以来,我已经在我的电脑上尝试过这个,任何有兴趣的人也可以尝试一下:

(1st(我的回答是发布的:

val start = Date().time
for (i in 1..10000) {
val listOfExpensesInSelectedDate = expenses.filter { it.date in selectedDates }
}
val end= Date().time
println(end - start)

平均时间结果:26毫秒(23毫秒-35毫秒(

(2nd(我对热键建议使用集合的回答:

val start = Date().time
for (i in 1..10000) {
val expSet = selectedDates.toSet()
val listOfExpensesInSelectedDate = expenses.filter { it.date in expSet }
}
val end= Date().time
println(end - start)

平均时间结果:70毫秒(50毫秒-86毫秒(

(3d(热键的答案:

val start = Date().time
for (i in 1..10000) {
val groups = expenses.groupBy { it.date }
val listOfExpensesInSelectedDate = selectedDates.flatMap { groups[it].orEmpty() }
}
val end= Date().time
println(end - start)

平均时间结果:100毫秒(74毫秒-150毫秒(

您可以通过首先按dateexpenses进行分组,然后选择并合并在selectedDates中具有键的组来简化和优化代码,如下所示:

val selectedDates = listOf("2018-08-12", "2018-08-13", "2018-08-14")
val expenses: List<Expense> = TODO("content omitted")
val groups = expenses.groupBy { it.date }
val listOfExpensesInSelectedDate = selectedDates.flatMap { groups[it].orEmpty() }

参见:groupByflatMap

最新更新