I have this code snippet ```.forEach { val (k,...
# codingconventions
e
I have this code snippet
Copy code
.forEach {
    val (k, v) = it.split(':')
    meta[k.trim()] = v.trim()
}
I though I could make it more concise with
associateTo
, but I still need two lines
Copy code
.associateTo(meta) {
    val (k, v) = it.split(':')
    k.trim() to v.trim()
}
unless I'm missing something, I'd revert to the first version
e
you probably could do
Copy code
.gropuingBy { it.substringBefore(':').trim() }
.aggregateTo(meta) { _, _, it, _ -> it.split(':')[1].trim() }
but that you have now is fine and clear enough
👍 1
k
Copy code
.associateTo(meta) { it.split(':').map(String::trim).zipWithNext().single() }
This also checks that your value doesn't contain
':'
- not sure if you've dealt with that possibility. You might want
.split(':', limit = 2)
.
e
there's also the possibility that there is no
:
in the string, in which case the code will fail
j
Do you really need a mutable map for this? Plain old
associate
is a bit cleaner. The other advantage of
associateTo
is that it returns the map, but I can’t tell if you’d need that without seeing more context
e
I didn't know about the split limit option, good to know
in case you may want to have the context, I'm porting this code to Kotlin MP
e
then
Copy code
.filter { ':' in it }
.associateTo(meta) {
    it.substringBefore(':').trim() to
        it.substringAfter(':').trim()
}
would be closer to that behavior
m
I often see using
let
in such situations
Copy code
.associateTo(meta) {
    it.split(':').let { (k, v) -> k.trim() to v.trim() }
}
👍 2
e
I don't see a reason to use let instead of val destructuring, but my point was that if the string doesn't contain
:
then the original code treats it as an empty value while split+bind will throw