简体   繁体   English

Kotlin - 按地图列表分组

[英]Kotlin - group by list of Maps

I have a fieldList variable.我有一个 fieldList 变量。

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.我想按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?在 Kotlin 中这样做最惯用的方法是什么?

I have an ugly looking working version in Java, but I am quite sure Kotlin has a nice way of doing it..我有一个丑陋的 Java 工作版本,但我很确定 Kotlin 有一个很好的方法。

it's just that I am not finding it so far !只是到目前为止我还没有找到它!

Any idea ?任何的想法 ?

Thanks谢谢

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 specific section_id . section_name对于特定的section_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.使用Map存储已知属性并使用Any存储StringList使用起来非常不方便且容易出错。

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"]) }
        )
    }

Playground操场

Also, as broot mentioned, prefer using data classes instead of such maps.此外,正如 broot 所提到的,更喜欢使用数据类而不是这样的映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM