Kotlin 最佳列表合并与操作技术

Kotlin 最佳列表合并与操作技术,kotlin,Kotlin,因此,我得到了一个(可变)的对列表,看起来像这样 ... Pair(IDENTIFIER, "A"), Pair(TICKTICK, "``"), Pair(IDENTIFIER, "_B") ... 我需要在列表中循环并结束此合并: ... Pair(IDENTIFER, "A_B") ... 因此,基本上找到所有出现的TICKTICK标记,并合并前两个标记(即,创建一个新的标记对,将字符串添加在一起) 我目前的想法是对进行查找,查找记号标记,然后删除上一个、当前的和下一个,然后插入一个新

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

...
Pair(IDENTIFIER, "A"),
Pair(TICKTICK, "``"),
Pair(IDENTIFIER, "_B")
...
我需要在列表中循环并结束此合并:

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

我目前的想法是对进行
查找,查找
记号
标记,然后删除上一个、当前的和下一个,然后插入一个新合并的标记

似乎应该有一种更自然的方式…。有什么想法吗


似乎我也没有访问迭代器()的权限。以前的
即使由Kotlin 1.2的

指示,您也可以使用新的加窗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]
}
下面是一个完整的可运行演示:


在Kotlin 1.1.x中没有带窗口的
函数,因此您必须自己实现它,或者对代码执行相同的操作。

在某些方面,这相当于字符串的
replace
方法来替换子字符串。是的。只是我需要跟踪生成的令牌类型。很好!但是为什么“好东西”总是离主要版本只有一次?我仍然在1.1.3:-(.给了我一些不同于我天真的
for循环的方法的想法。@RobertEkendahl,这里有一个如果有用的话。哇,你是Kotlin Fu,很强大。我将尝试使用这个方法和你上面的例子,看看会发生什么