代码之家  ›  专栏  ›  技术社区  ›  svkaka

Kotlin有没有一种方法可以将map<k out t,list<v out t>展平到list<t>

  •  1
  • svkaka  · 技术社区  · 6 年前

    我想把地图转换成列表

    我有

    mapOf("a" to listOf(1,2),
          "b" to listOf(3,4)
    )
    

    我希望结果是

    listOf("a", 1, 2, "b", 3, 4)
    

    顺序必须是键及其值、键及其值…

    科特林有什么能帮我的吗?

    3 回复  |  直到 6 年前
        1
  •  3
  •   Roland    6 年前

    我的第二个评论变体作为 Map<String, List<Int>> :

    mapOf("a" to listOf(1,2),
          "b" to listOf(3,4))
         .flatMap { (key, values) -> listOf(key) + values }
    

    给出一个 List<Any> 键后面跟着它们的值。

    此示例使用 destructuring declaration Map.flatMap .

        2
  •  2
  •   Yoni Gibbs    6 年前

    更新 :以下答案是在问题更新和更改地图创建方式之前编写的(有关详细信息,请参阅问题的历史记录)。现在的问题是,下面的答案将不再有效。不过,我相信,它确实像最初提出的那样适用于这个问题。

    @罗兰说的对,你的映射永远不会产生那个列表,因为在映射中对于任何给定的键只能有一个值。所以我认为你需要用一个成对的列表来替换这个地图。然后您可以将其分组并展开映射,以获得所需的结果:

    val pairs = listOf("a" to 1, "a" to 2, "b" to 3, "b" to 4)
    val result = pairs
            .groupBy { it.first }
            .flatMap { (key, values) -> listOf(key).plus(values.map { it.second }) }
    

    另一个稍有不同的选项,您可能认为它更具可读性,是:

    val result = pairs
            .groupBy({ it.first }, { it.second })
            .flatMap { (key, values) -> listOf(key).plus(values) }
    
        3
  •  1
  •   leonardkraemer    6 年前

    你可以 flatMap 结束 map.entries . 看看这个 function :

    val map = mapOf("a" to listOf(1,2), 
                    "b" to listOf(3,4))
    println(map)
    val flattened : List<Any> = map.entries.flatMap {entry -> 
        //create list with key as only element, must be type <Any> to add other stuff later
        val list = mutableListOf<Any>(entry.key)
        //add values
        list.addAll(entry.value)
        list
    }
    println(flattened)
    

    印刷品:

    {a=[1, 2], b=[3, 4]}
    [a, 1, 2, b, 3, 4]
    

    @罗兰的回答激发了这个更简单、更惯用的版本。它本质上是一样的,但是把所有东西都塞进一行:

     val flattened: List<Any> = map.flatMap {entry -> 
            listOf(entry.key) + entry.value
     }