是否可以根据所需的条件匹配过滤和映射两个Collection,如下所示:
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
)
提供了上面给定的代码,我试图返回与其他字符串列表中的日期匹配的费用列表。在上面的示例中,我同时使用了Loop和filter函数来获得所需的结果。但是有可能避免for循环和过滤并在单行代码中映射两个Collection吗?
答案 0 :(得分:4)
您可以通过先按expenses
对date
进行分组,然后选择并合并在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() }
答案 1 :(得分:1)
您可以仅使用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)
平均时间结果:26ms(23ms-35ms)
(第二个),我的回答与热键建议一起使用:
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)
平均时间结果:70ms(50ms-86ms)
(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)
平均时间结果:100ms(74ms-150ms)