Kotlin: несколько операций над коллекциями

Изменить:

Пришлось возвращать набор пассажиров, у которых было большинство скидок. Решение этой загадки было следующим:

  1. Извлечь все количество пассажиров на карте
  2. Извлеките все количество пассажиров на карте, получивших скидки.
  3. Затем в цикле мне пришлось применить лямбду, чтобы найти процент и посмотреть, получили ли пассажиры скидку на большинство поездок.
  4. Добавьте их в набор и верните его.

Пожалуйста, смотрите код ниже,

fun findDiscountedPassengers(): Set<Passenger> {
    var discountedPassengerList: MutableList<Passenger> = emptyList<Passenger>().toMutableList()
    var passengerTripCountMap = trips.flatMap { it.passengers }.groupingBy { it }.eachCount()
    var passengerDiscountedTripsMap = trips.filter { it.discount != null }
            .flatMap { it: Trip -> it.passengers }
            .groupingBy { it }
            .eachCount()

    val findPercentage = ...

    passengerDiscountedTripsMap.forEach { it: Map.Entry<Passenger, Int> ->
        val totalTripsCount: Double? = passengerTripCountMap.get(it.key)?.toDouble()
        if (findPercentage(it.value.toDouble(), totalTripsCount?:0.0) > majorPercentage) {
            discountedPassengerList.add(it.key)
        }
    }
    return discountedPassengerList.toSet()
}

Мой код кажется немного более похожим на Java, чем Kotlin, поскольку он не такой лаконичный/короткий или оптимизированный. Я создал две разные группы, что привело к двум картам; затем создайте цикл для применения остальной логики. Я думаю, что можно удалить ненужные шаги.

Пример: преобразование списка в набор для возврата результата и т. д.

Как я могу избежать создания двух групп, приводящих к двум разным картам? Какие оптимизации я могу применить на этапах с 1 по 4? Могу ли я каким-либо образом использовать Partition (не уверен в концепции), чтобы уменьшить количество шагов, которые я предпринял в приведенном выше коде?

Спасибо.


person Ahmed    schedule 13.01.2019    source источник
comment
Я не уверен, правильно ли я понимаю, но Здесь может быть полезен оператор partition, если вы хотите разделить список на основе какого-либо предиката. Например. trips.partition { it.discount != null && it.discount > 0.0 } вернет Пару поездок со скидкой и без.   -  person Damon Baker    schedule 14.01.2019
comment
Я не уверен, что ты там делаешь. почему вы делаете eachCount, а потом берете только ключи? Не могли бы вы поделиться структурами данных, пожалуйста?   -  person s1m0nw1    schedule 14.01.2019
comment
Если вы можете сделать это в java, возможно, вы захотите поделиться кодом java (псевдо). Код часто более понятен, чем естественный язык.   -  person leonardkraemer    schedule 14.01.2019
comment
Извините за путаницу. Позвольте мне разместить здесь свое полное решение вместе с вопросом, который я пытался решить. Через несколько вы увидите мои правки в вопросе.   -  person Ahmed    schedule 15.01.2019


Ответы (1)


Как уже упоминалось в комментариях, я не совсем понимаю ваш вариант использования и думаю, что ваше использование groupingBy не имеет смысла. Вы пытаетесь подсчитать количество пассажиров, которые появляются внутри trips, и я предлагаю следующее:#

val (passengersWithDiscount, passengersWithoutDiscount) = trips.partition { it.discount != null && it.discount > 0.0 }.let { (with, withOut) ->
    val counter = { trips: List<Trip> -> trips.flatMap { it: Trip -> it.passengers }.count() }
    counter(with) to counter(withOut)
}

С помощью partition мы разделяем данные на основе условия. После этого мы объявляем функцию-счетчик, которая преобразует List<Trip> в количество пассажиров. Затем эта функция применяется к обоим спискам результатов, которые мы получили из файла partition.

person s1m0nw1    schedule 14.01.2019
comment
Пожалуйста, смотрите вопрос сейчас. - person Ahmed; 15.01.2019