Hi All, I have a `Iterable<A>` and want to c...
# announcements
x
Hi All, I have a
Iterable<A>
and want to create a
Map<A, Int>
with a function
f: A -> Int?
. The values in the map cannot be null. So I write something like this:
Copy code
iterable
  .map { Pair(it, f(it)) }      // Iterable<Pair<A, Int?>>
  .filter { it.second != null } // still Iterable<Pair<A, Int?>> but we can be sure the Int is not null
  .map { Pair(it.first, it.second!!) } // now it is Iterable<Pair<A, Int>>
  .toMap()
Is there any better way?
c
Copy code
iterable.mapNotNull { thing ->
  f(thing)?.let { thing to it }
}
4
👍 3
❤️ 1
j
Copy code
iterable
  .associateWith { f(it) }
  .filterValues { it != null }
d
James that still produces a
Map<A, Int?>
instead of
Map<A, Int>
j
True, in this case I think its fine to then cast it to
Map<A, Int>
Or something like:
Copy code
iterable
  .associateWith { f(it) }
  .filterValues { it != null }
  .mapValues { it ?: 0 }
d
Unchecked casts should be avoided if you can...
j
IMO the cast is fine when it's guaranteed to be safe 🤷‍♂️
x
The cast is fine, however IntelliJ will give a warning, right? Then I don't know which warnings are good, which are bad. The
iterable.mapNotNull { thing -> f(thing)?.let { thing to it } }
is excellent. I always wonder what's the equivalent of Scala's
.collect
in Kotlin.
mapNotNull ?.let
might not be that powerful but good enough.
d
I think
mapNotNull
is the closest equivalent