Kotlin-两个集合中的过滤器/地图

时间:2018-08-21 18:58:09

标签: collections kotlin

是否可以根据所需的条件匹配过滤和映射两个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吗?

2 个答案:

答案 0 :(得分:4)

您可以通过先按expensesdate进行分组,然后选择并合并在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

答案 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)