https://kotlinlang.org logo
Title
x

xxfast

09/20/2021, 1:11 AM
Hi all, whats the best way to achieve this?
val actual = listOf(
  Item(type = A, value = 1),
  Item(type = B, value = 2),
  Item(type = B, value = 3)
)

val expect = mapOf(
  A to listOf(Item(type = A, value = 1)),
  B to listOf(Item(type = B, value = 2), Item(type = B, value = 3)),
  C to emptyList()
)
I know of
actual
  .groupByTo(
    mutableMapOf(
      A to mutableListOf(),
      B to mutableListOf(),
      C to mutableListOf(),
    )
 ) { item -> item.type }
but this is not quite readable, and was wondering if there’s a better way
actually - think i might’ve solved this myself
listOf(A, B, C)
  .map { type -> type to actual
    .filter { item -> item.type == type } 
  }
just had to reverse my way of thinking
d

dave08

09/20/2021, 2:35 AM
In the second one you're going through actual 3 times, maybe the first with
list(A,B,C).map { it to mutableListOf() }
to make the map?
t

Tobias Suchalla

09/20/2021, 6:00 AM
val map: Map<Type, List<Item>> = actual.groupBy { it.type }
However, Type
C
would be missing in the map as there is no such type in
actual
.
Depending on your logic, you could instead use the following when retrieving values from the map:
val itemsForC = map[C] ?: emptyList()
r

Roukanken

09/20/2021, 7:49 AM
maybe something this would make more sense?
val result = actual
    .groupBy { it.type }
    .withDefault { emptyList() }
This assumes that C is subtype of common type of A & B, and not some higher supertype ofc, otherwise you would have to do some extra casting in there somewhere but this gets you map that has values from list as you want, and at everything else that is a valid key, it will respond with empty list
1
e

ephemient

09/20/2021, 8:08 AM
if you need a supertype, type annotation can work without explicit casting, e.g.
val result = actual
    .groupBy<Item, SupertypeOfABC> { it.type }
    .withDefault { emptyList() }