在完全不可变的层次结构中将元素添加到子列表中的惯用方法

时间:2018-05-01 12:37:20

标签: kotlin

我有以下数据结构:

var foo: Map<String, List<String>> = emptyMap()
foo += mapOf(
        "1" to listOf("a", "b"),
        "2" to listOf("a", "b"),
        "3" to listOf("a", "b")
)

地图和子列表都是不可变的。我现在想要将元素c添加到地图中第一个元素的列表中。

我提出了这个解决方案:

foo += "1" to (foo["1"] ?: emptyList()) + "c"

但这真的是惯用的方式吗?

根据@hotkeys回答更新

foo += "1" to foo["1"].orEmpty() + "c"

2 个答案:

答案 0 :(得分:1)

您可以检查的另一种方法是incubating library kotlinx.collections.immutable使用的方法(或仅使用该库)。它允许您.mutate { ... }一个地图,它使用应用的突变创建该地图的不可变副本:

val m = immutableHashMapOf("1" to listOf("a", "b"))

val result = m.mutate { it["1"] = it["1"].orEmpty() + "c" }

另见:.orEmpty()

但是,标准库中没有等同于.mutate { ... },但您可以为只读Map定义自己的扩展程序。

答案 1 :(得分:0)

除非出现问题,否则可以加入声明和作业。 制作地图&amp;列表可变,因为需要改变

var foo: MutableMap<String, MutableList<String>> = mutableMapOf(
        "1" to mutableListOf("a", "b"),
        "2" to mutableListOf("a", "b"),
        "3" to mutableListOf("a", "b")
)

我们可以在下面的块中使用

when {
    foo.containsKey("1") -> foo["1"]?.add("c")
    else -> foo["1"] = mutableListOf("c")

}