最佳列表合并和操作技术

Rob*_*ahl 2 kotlin

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

...
Pair(IDENTIFIER, "A"),
Pair(TICKTICK, "``"),
Pair(IDENTIFIER, "_B")
...
Run Code Online (Sandbox Code Playgroud)

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

...
Pair(IDENTIFER, "A_B")
...
Run Code Online (Sandbox Code Playgroud)

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

我目前的想法是for寻找TICKTICK令牌,然后删除上一个、当前和下一个,然后插入一个新合并的令牌。

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

iterator().previous即使此链接指出,我似乎也无权访问

hot*_*key 5

在 Kotlin 1.2 中,您还可以使用新的windowedstdlib 函数将元素表示为滑动窗口的快照,例如

println(listOf(1, 2, 3, 4, 5, 6).windowed(3))
// [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
Run Code Online (Sandbox Code Playgroud)

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

val pattern = listOf(IDENTIFIER, TICKTICK, IDENTIFIER)

// Stores indices of items that are not replaced:
val indicesOfNormalItems = items.indices.toMutableSet()
Run Code Online (Sandbox Code Playgroud)

窗口上的循环也将结果项收集到具有三元组第一个索引的键的映射中:

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()
Run Code Online (Sandbox Code Playgroud)

然后收集结果,将未替换的项目与地图中的值组合起来:

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

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

在 Kotlin 1.1.x 中没有windowed函数,所以你必须自己实现它或者用你的代码做同样的事情。