Reputation: 14611
I am currently using a Kotlin function to extract a map out of a Json structure with key value pairs.
The JSON used to build the map is contains a label and a value:
"values": [
{
"label": "Email",
"value": "email"
},
{
"label": "Social media",
"value": "socialMedia"
},
{
"label": "Word of mouth",
"value": "wordOfMouth"
},
{
"label": "Newspaper",
"value": "newspaper"
}
],
The JSON "label" should become the key of the map and the "value" its value.
This is the code used to extract and convert the JSON to a map using Java 8's stream collect method.
fun extractValue(jsonNode: JsonNode?): Map<String, String> {
val valuesNode = jsonNode?.get("values") ?: mapper.createArrayNode()
return valuesNode.map { Pair(it.get("label")?.asText() ?: "", it.get("value")?.asText() ?: "") }
.stream().collect({ HashMap<String, String>()}, { m, p -> m.put(p.first, p.second) } , { m, p -> })
}
How do you write the part with stream().collect in idiomatic Kotlin? What alternatives do you have to replace
stream().collect()
in this specific case?
Upvotes: 3
Views: 888
Reputation: 9944
So you have a list of pairs and you want to convert it to a map? You can just replace your .stream().collect(...)
with Kotlin's toMap()
.
From the Kotlin docs:
fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V>
Returns a new map containing all key-value pairs from the given collection of pairs.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-map.html
Upvotes: 3
Reputation: 30686
the associateBy method is like as java Collectors#toMap
, so you can simply done it in kotlin as below:
fun extractValue(jsonNode: JsonNode?): Map<String, String> {
// key mapping ---v
return jsonNode?.get("values")?.associateBy({ it.get("label")?.asText()?:"" }){
it.get("value")?.asText() ?: "" // value mapping
} ?: emptyMap()
// ^--- default value is an empty map
}
Upvotes: 2