Kotlin:最佳列表合并技术?

时间:2017-11-03 15:35:59

标签: kotlin

Kotlin列表操作/合并问题:

所以我得到了一个(可变的)对列表,看起来像这样

... Pair(IDENTIFIER, “A”), Pair(TICKTICK, “``”), Pair(IDENTIFIER, "_B") ...

我需要遍历列表并结束合并到此:

... Pair(IDENTIFER, "A_B") ...

所以基本上找到所有TICKTICK标记出现并合并前两个标记(即,创建一个新的对,并将字符串加在一起)。

我目前的想法是for查找TICKTICK代币,然后删除上一个,当前和下一个,然后插入一个新合并的代币。

似乎应该有一种更自然的方式...... 任何想法

即使this link

指示,我似乎无法访问iteraror().previous

1 个答案:

答案 0 :(得分:4)

使用Kotlin 1.2,您还可以使用新的windowed stdlib函数来表示元素作为滑动窗口的快照,例如

println(listOf(1, 2, 3, 4, 5, 6).windowed(3))
// [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]

然后针对窗口检查模式IDENTIFIER, TICKTICK, IDENTIFIER,如果匹配(如果三个项目尚未替换),则将用这些索引替换项目的信息存储为单个。

val pattern = listOf(IDENTIFIER, TICKTICK, IDENTIFIER)

// Stores indices of items that are not replaced:
val indicesOfNormalItems = items.indices.toMutableSet()

循环窗口,它还使用三元组的第一个索引的键将结果项目收集到地图中:

val replaced = items.withIndex().windowed(pattern.size) { window ->
    val kinds = window.map { (_, item) -> item.first }
    if (kinds == pattern) {
        val windowFirstIndex = window.first().index
        if (windowFirstIndex in indicesOfNormalItems) {
            indicesOfNormalItems.removeAll(window.map { it.index })
            val (first, _, third) = window.map { it.value.second }
            return@windowed windowFirstIndex to (IDENTIFIER to first + third)
        }
    }
    null
}.filterNotNull().toMap()

然后收集结果,将其与未替换的项目和地图中的值相结合:

val result = items.indices.mapNotNull { index ->
    if (index in indicesOfNormalItems)
        items[index] else
        replaced[index]
}

这是一个完整的可运行演示:(link)

在Kotlin 1.1.x中没有windowed功能,所以你必须自己实现它或者对你的代码执行相同的操作。