I have a fieldList variable.
val fieldList: List<MutableMap<String, String>>
// fieldList Data :
[ {
"field_id" : "1",
"section_id" : "1",
"section_name" : "section1",
"field_name" : "something_1"
}, {
"field_id" : "2",
"section_id" : "1",
"section_name" : "section1",
"field_name" : "something_2"
}, {
"field_id" : "3",
"section_id" : "2",
"section_name" : "section2",
"field_name" : "something_3"
}, {
"field_id" : "4",
"section_id" : "3",
"section_name" : "section3",
"field_name" : "something_4"
} ]
And I want to group by section_id.
The results should be as follows:
val result: List<MutableMap<String, Any>>
// result Data :
[
{
"section_id": "1",
"section_name": "section1",
"field": [
{
"id": “1”,
"name": "something_1"
},
{
"id": “2”,
"name": "something_2"
}
]
},
{
"section_id": "2",
"section_name": "section2",
"field": [
{
"id": “3”,
"name": "something_3"
}
]
},
.
.
.
]
What is the most idiomatic way of doing this in Kotlin?
I have an ugly looking working version in Java, but I am quite sure Kotlin has a nice way of doing it..
it's just that I am not finding it so far !
Any idea ?
Thanks
CodePudding user response:
Assuming we are guaranteed that the data is correct and we don't have to validate it, so:
- all fields always exist,
section_name
is always the same for a specificsection_id
.
This is how you can do this:
val result = fieldList.groupBy(
keySelector = { it["section_id"]!! to it["section_name"]!! },
valueTransform = {
mutableMapOf(
"id" to it["field_id"]!!,
"name" to it["field_name"]!!,
)
}
).map { (section, fields) ->
mutableMapOf(
"section_id" to section.first,
"section_name" to section.second,
"field" to fields
)
}
However, I suggest not using maps and lists, but proper data classes. Using a Map
to store known properties and using Any
to store either String
or List
is just very inconvenient to use and error-prone.
CodePudding user response:
Another way:
val newList = originalList.groupBy { it["section_id"] }.values
.map {
mapOf(
"section_id" to it[0]["section_id"]!!,
"section_name" to it[0]["section_name"]!!,
"field" to it.map { mapOf("id" to it["field_id"], "name" to it["field_name"]) }
)
}
Also, as broot mentioned, prefer using data classes instead of such maps.