Kotlin:从列表中的嵌套集中查找计数(更多功能方法)

Ahm*_*med 2 java kotlin kotlin-extension kotlin-android-extensions

下面的功能创建一个地图,获取乘客数量> minTrips的乘客数量.代码完全正常.请看下面

fun List<Trip>.filter(minTrips : Int): Set<Passenger> {
    var passengerMap: HashMap<Passenger, Int> = HashMap()

    this.forEach { it: Trip ->
        it.passengers.forEach { it: Passenger ->
            var count: Int? = passengerMap.get(it)
            if (count == null) {
                count = 1
                passengerMap.put(it, count)
            } else {
                count += 1
                passengerMap.put(it, count)
            }
        }
    }

    val filteredMinTrips: Map<Passenger, Int> = passengerMap.filterValues { it >= minTrips }
    println (" Filter Results = ${filteredMinTrips}")
    return filteredMinTrips.keys
}
Run Code Online (Sandbox Code Playgroud)

虽然这是用Kotlin编写的,但似乎代码最初是用Java编写的,然后转换为Kotlin.如果它真的是用Kotlin写的,我相信这不会是这么多行代码.如何减少代码行?解决这个问题的更有趣的方法是什么?我可以使用哪些功能或功能直接提取乘客设置> minTrips?这是一个太多的代码,似乎很疯狂.任何指针在这里都会有所帮助.

Tod*_*odd 6

你可以做到这一点的一种方法是利用Kotlin的flatmap和分组调用.通过在所有旅行中创建所有乘客的列表,您可以对它们进行分组,计算并返回超过一定数量的乘客.

假设你有这样的数据类(仅限基本细节):

data class Passenger(val id: Int)
data class Trip(val passengers: List<Passenger>)
Run Code Online (Sandbox Code Playgroud)

我能写出来:

fun List<Trip>.frequentPassengers(minTrips: Int): Set<Passenger> =
    this
       .flatMap { it.passengers }
       .groupingBy { it }
       .eachCount()
       .filterValues { it >= minTrips }
       .keys
Run Code Online (Sandbox Code Playgroud)

这很好,因为它是一个单独的表达式.通过它,我们看看每一个,Trip并提取所有Passengers.如果我们刚刚在map这里完成,我们会有List<List<Passenger>>,但我们想要一个List<Passenger>平面图来实现这一目标.接下来,我们groupByPassenger对象本身,并调用eachCount()返回的对象上,给我们一个Map<Passenger, Int>.最后,我们按照我们感兴趣的乘客过滤地图,然后返回密钥集.

请注意,我重命名了您的功能,List已经有了filter它,即使签名不同,我发现它令人困惑.