是否有像 map 这样的集合函数将列表中的每个项目都变成两个项目?

Jol*_*151 3 kotlin

假设我有一个整数列表,例如:

val list = listOf(1, 2, 3, 5, 8, 13)
Run Code Online (Sandbox Code Playgroud)

我想运行一个操作来创建一个类似的列表,但在每个元素之后都有一个附加元素。例如,我们应该能够-99在每个元素之后添加一个这样的:

[1, -99, 2, -99, 3, -99, 5, -99, 8, -99, 13, -99]

我可以使用 forEach 循环和临时列表轻松完成此操作,如下所示:

val list = listOf(1, 2, 3, 5, 8, 13)
val tempList = mutableListOf<Int>()
list.forEach {
    tempList.add(it)
    tempList.add(-99)
}
println(tempList) // [1, -99, 2, -99, 3, -99, 5, -99, 8, -99, 13, -99]
Run Code Online (Sandbox Code Playgroud)

但这似乎是不必要的冗长和命令。我发现的另一种方法是将每个项目映射到一个包含两个元素的列表,创建一个列表列表,然后展平结果。例子:

val list = listOf(1, 2, 3, 5, 8, 13)
val mapFlatten = list
    .map { listOf(it, -99) }
    .flatten()
 
println(mapFlatten) // [1, -99, 2, -99, 3, -99, 5, -99, 8, -99, 13, -99]
Run Code Online (Sandbox Code Playgroud)

然而,创建一个列表列表然后展平似乎是不必要的多余。是否有任何列表操作可以让我们以更简单的方式执行此操作?

Jof*_*rey 6

您可以通过flatMap直接使用来简化您的第二个选项:

val list = listOf(1, 2, 3, 5, 8, 13)
val mapFlatten = list.flatMap { listOf(it, -99) }
Run Code Online (Sandbox Code Playgroud)

从技术上讲,您仍然拥有这些中间列表,但我不确定它是否可以进一步简化。

如果你真的有很大的列表并且你担心额外的分配,你可以回退到像你一样手动构建一个列表,除非你不害怕实验功能并且可以使用buildList

val list = listOf(1, 2, 3, 5, 8, 13)
val mapFlatten = buildList(2 * list.size) {
    list.forEach {
        add(it)
        add(-99)
    }
}
Run Code Online (Sandbox Code Playgroud)