如何分离受 constrainOnce() 约束的 Sequence<> 的独立遍历?

问题描述 投票:0回答:1

我知道 constrainOnce() 限制 Kotlin 序列仅被约束一次,但似乎 非常有限制性。我想对前 3 个(例如)元素做一些事情,然后做其他事情 之后的元素:


class TestClassGeneric {
    @Test
    fun t1() {
        val seq1 = sequenceOf(1,2,3,4,5,6,7).constrainOnce()
        seq1.take(3).forEach() { println(it) }
        seq1.drop(3).forEach() { println(it) }

    }
}

代码在包含 drop() 的行处失败,因为尝试了第二次遍历序列。为什么是这样 ?我还没有迭代超越前 3 项!

如果我使用

drop(2)
drop(1)
,我预计它会失败,但在
drop(3)
失败似乎非常受限制。

真的应该丢弃序列的其余部分吗?如何对前几个元素执行某些操作,将其尾部作为子序列传递到其他地方。

有一个作者回答的问题如何修改Kotlin序列的前缀但保留尾部?但我无法理解他给出的答案是如何工作的。它涉及在该迭代器上仅使用单个

Iterator
asSequence()
。但是,我无法确定迭代器是否应该在连续使用它之间前进。另外,在作用域函数中执行所有这些操作是否有任何意义,
.let{}

我生成序列并需要根据它的开头做一些事情。我为此

HybridSequence(ps:Sequence): Sequence
创建了一个包装类,其中
init{}
对包装的序列执行了
take(1)
将其写入
List
,并根据第一个元素设置了一个可读属性,

它提供了一个迭代器,该迭代器将从列表中生成第一个元素,然后生成所传递内容的尾部(在输入上使用 drop(2) )。显然,这会失去第一个元素的惰性评估,但这对我来说没问题。

无论如何,它失败了,因为当我尝试使用 drop(2) 时,底层序列似乎被丢弃了。我的代码有点麻烦,所以我创建了上面的最小版本。

我实际上/需要/我的

Sequence
constrainOnce()
,但我想让它足够强大以支持这样的。

kotlin iterator sequence
1个回答
0
投票

有点尴尬,但是你可以使用

.partition
基于索引
.withIndex

fun t1() {
    val seq1 = sequenceOf(1, 2, 3, 4, 5, 6, 7).constrainOnce()
    val (firstPartition, secondPartition) = seq1
        .withIndex()
        .partition{ (_, i) ->  i < 3}
    val firstSeq = firstPartition.map { (_, v) -> v }
    val secondSeq = secondPartition.map { (_, v) -> v }
    firstSeq.forEach{ println(it)}
    secondSeq.forEach{ println(it)}
}
© www.soinside.com 2019 - 2024. All rights reserved.