在 Kotlin 中将列表转换为映射并自定义此转换

3
var listOfNums = listOf(1,9,8,25,5,44,7,95,9,10)
var mapOfNums = listOfNums.map { it to it+1 }.toMap()
println(mapOfNums)

结果

{1=2, 9=10, 8=9, 25=26, 5=6, 44=45, 7=8, 95=96, 10=11}

虽然我需要这个结果,但它会将下一个元素的内容添加到当前元素中,而我需要将当前元素映射到下一个元素

我的目标结果

{1=9, 8=25, 5=44, 7=59, 9=10}

这将会更容易,因为1.2版本即将推出窗口化和分块功能。 - Ruckus T-Boom
3个回答

6

对于 Kotlin 1.1:

首先,使用 zip 创建一个包含相邻对的列表,然后删除每两个一组的其中一个,再将其转换为 Map。就像这样:

val list = listOf(1,9,8,25,5,44,7,95,9,10)
val mapOfNums = list.zip(list.drop(1))
                    .filterIndexed { index, pair -> index % 2 == 0 }
                    .toMap())

对于Kotlin 1.2:

Kotlin 1.2引入了chunked函数,这将使此过程变得更加容易。该函数将列表分成给定长度的子列表。然后您可以执行以下操作:

val list = listOf(1,9,8,25,5,44,7,95,9,10)
val mapOfNums = list.chunked(2).associate { (a, b) -> a to b }

3
也可以写成:list.chunked(2).associateBy({ it.first }, { it.last() })。这行代码的作用是将一个列表按照每两个元素一组进行分组,然后将每组的第一个元素作为key,第二个元素作为value,最终返回一个键值对映射的Map对象。 - voddan
@voddan 哦,好的。已修复。 - marstran
我在这里展示了使用1.1的chunked实现链接 - Abhijit Sarkar

1
我们可以跨越每个第二个索引,并将listOfNums[it]映射到listOfNums[it+1]。
val listOfNums = listOf(1,9,8,25,5,44,7,95,9,10)
val mapOfNums = mutableMapOf<Int, Int>()
(listOfNums.indices step 2).forEach {
    mapOfNums[listOfNums[it]] = listOfNums[it + 1]
}
println(mapOfNums)

编辑: 另一个更好的解决方案由ephemient提出:

 (1..listOfNums.lastIndex step 2).associate { listOfNums[it - 1] to listOfNums[it] }

优雅!

此答案假设listOfNums的大小为偶数。 - Arsala Bangash
1
(1..listOfNums.lastIndex step 2).associate { listOfNums[it - 1] to listOfNums[it] } 避免了可变映射以及丢弃了末尾奇数元素。 - ephemient

1
借助于 RxJava 的帮助。
import io.reactivex.Observable

...

val listOfNums = listOf(1,9,8,25,5,44,7,95,9,10)
val mapOfNums = Observable.fromIterable(listOfNums)
        .buffer(2)
        .map { it[0] to it[1] }
        .collect(
                { mutableMapOf<Int, Int>() },
                { map: MutableMap<Int, Int>, (first, second) -> map.put(first, second) }
        )
        .blockingGet()
println(mapOfNums)
// {1=9, 8=25, 5=44, 7=95, 9=10}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接