I want to create a collection (in this case a map due to the extended function 'groupBy') that maps an IntRange to a list of a data class, which members are determined whether an int inside the data class is within the IntRange. The IntRanges are 0..9, 10..19, 20..29, etc.
Concrete example:
data class Trip(
val (...)
val distance: Double
)
[...]
val mappedTrips = trips.groupBy {
((it.duration-(it.duration)%10))..((it.duration-(it.duration)%10)+9) }
Explicitly the
((it.duration-(it.duration)%10))..((it.duration-(it.duration)%10)+9)
part seems to be not very concise, hard to read and therefore I was wondering if there is a way to make it more efficient, meaning more easy to read, concise.
Thank you in advance.
Edit:
TaxiPark Class
package taxipark
data class TaxiPark(
val allDrivers: Set<Driver>,
val allPassengers: Set<Passenger>,
val trips: List<Trip>)
data class Driver(val name: String)
data class Passenger(val name: String)
data class Trip(
val driver: Driver,
val passengers: Set<Passenger>,
// the trip duration in minutes
val duration: Int,
// the trip distance in km
val distance: Double,
// the percentage of discount (in 0.0..1.0 if not null)
val discount: Double? = null
) {
// the total cost of the trip
val cost: Double
get() = (1 - (discount ?: 0.0)) * (duration + distance)
}
Task
Find the most frequent trip duration among minute periods 0..9, 10..19, 20..29, and so on.
Return any period if many are the most frequent, return null
if there're no trips.
Test sample
class TestTask5TheMostFrequentTripDurationPeriod {
private fun testDurationPeriod(expected: Set<IntRange?>, tp: TaxiPark) {
val actual = tp.findTheMostFrequentTripDurationPeriod()
val message = "Wrong result for 'findTheMostFrequentTripDurationPeriod()': $actual."
if (expected.size <= 1) {
Assert.assertEquals(
message + tp.display(),
expected.firstOrNull(), actual)
} else {
Assert.assertTrue(message +
tp.display() +
"\nPossible results: $expected" +
"\nActual: $actual\n",
actual?.let { it in expected } ?: expected.isEmpty())
}
}
@Test
fun test00() = testDurationPeriod(setOf(null), taxiPark(0..1, 0..10))
@Test
fun test01() {
// The period 30..39 is the most frequent since there are two trips (duration 30 and 35)
testDurationPeriod(setOf(30..39), taxiPark(1..3, 1..5,
trip(1, 1, duration = 10),
trip(3, 4, duration = 30),
trip(1, 2, duration = 20),
trip(2, 3, duration = 35)))
}
@Test
fun test02() = testDurationPeriod(setOf(30..39), taxiPark(0..5, 0..9,
trip(0, listOf(2, 9), duration = 14, distance = 25.0),
trip(1, listOf(8), duration = 39, distance = 37.0, discount = 0.2),
trip(5, listOf(0, 5), duration = 27, distance = 28.0, discount = 0.3),
trip(4, listOf(0, 6), duration = 33, distance = 14.0),
trip(2, listOf(5, 1, 4, 3), duration = 2, distance = 15.0),
trip(4, listOf(7), duration = 27, distance = 2.0),
trip(4, listOf(4, 6), duration = 31, distance = 31.0),
trip(3, listOf(9, 0), duration = 34, distance = 7.0),
trip(5, listOf(3), duration = 25, distance = 33.0),
trip(1, listOf(0, 7, 2, 3), duration = 13, distance = 17.0))
)
}
trips.groupBy { it.duration / 10 }
? \$\endgroup\$