【问题标题】:Kotlin - group by list of MapsKotlin - 按地图列表分组
【发布时间】:2021-12-22 21:33:45
【问题描述】:

我有一个 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"
} ]

我想按 section_id 分组。

结果应该如下:

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"
         }
      ]
   },
   .
   .
   .
]

在 Kotlin 中最惯用的方法是什么?

我有一个丑陋的 Java 工作版本,但我很确定 Kotlin 有一个很好的方法..

只是到现在还没有找到!

有什么想法吗?

谢谢

【问题讨论】:

    标签: list kotlin lambda collections


    【解决方案1】:

    假设我们保证数据是正确的并且我们不必验证它,那么:

    • 所有字段始终存在,
    • 对于特定的section_idsection_name 始终相同。

    你可以这样做:

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

    但是,我建议不要使用地图和列表,而是使用适当的数据类。使用Map 存储已知属性并使用Any 存储StringList 使用起来非常不方便且容易出错。

    【讨论】:

      【解决方案2】:

      另一种方式:

      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

      另外,正如 broot 所提到的,更喜欢使用数据类而不是此类映射。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-12
        • 2022-01-20
        • 2019-05-30
        • 2020-10-13
        相关资源
        最近更新 更多