Hi all, whats the best way to achieve this? ```val...
# stdlib
x
Hi all, whats the best way to achieve this?
Copy code
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
Copy code
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
Copy code
listOf(A, B, C)
  .map { type -> type to actual
    .filter { item -> item.type == type } 
  }
just had to reverse my way of thinking
d
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
Copy code
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:
Copy code
val itemsForC = map[C] ?: emptyList()
r
maybe something this would make more sense?
Copy code
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
if you need a supertype, type annotation can work without explicit casting, e.g.
Copy code
val result = actual
    .groupBy<Item, SupertypeOfABC> { it.type }
    .withDefault { emptyList() }