Kotlin 产量示例

Kotlin yield example

提问人:ArekBulski 提问时间:11/8/2023 更新时间:11/8/2023 访问量:42

问:

我正在学习 Kotlin,出于对它的热爱,我无法弄清楚产量/顺序。有人可以更正我的代码吗?

fun Sequence<Int>.mapIterable(transform: (Int)->Int) = sequence {
    this.forEach({ x -> yield(transform(x)) })
}

fun Sequence<Int>.product(): Int {
    return this.reduce({ acc,x -> acc*x })
}

infix fun Int.powerof(exponent: Int): Int {
    return (1..exponent).mapIterable({ x -> this }).product()
}

fun main() {
    println(2 powerof 10)
}
Kotlin 序列 产生 可迭代

评论

0赞 Sweeper 11/8/2023
你想做什么,代码有什么问题?
0赞 Sweeper 11/8/2023
你为什么要写一个已经有的?你想与什么不同?mapIterablemapmapIterablemap
0赞 ArekBulski 11/8/2023
我想要一个贪婪地返回迭代器而不是列表的地图版本。
1赞 Sweeper 11/8/2023
懒。Sequence.map
1赞 Sweeper 11/8/2023
它。否则,您将调用返回 .(1..exponent).asSequence().map(...)mapList

答:

0赞 ArekBulski 11/8/2023 #1

正如@Sweeper建议的:

fun Sequence<Int>.product(): Int {
    return this.reduce({ acc,x -> acc*x })
}

infix fun Int.powerof(exponent: Int): Int {
    return (1..exponent).asSequence().map({ this }).product()
}

fun main() {
    println(2 powerof 10)
}
4赞 Sweeper 11/8/2023 #2

mapIterable不编译,因为指的是 lambda 的接收器,这是一个 .这就是允许您调用 .你的意思是 的接收器,你可以把它写成 。thissequence { ... }SequenceScope<Int>SequenceScopeyieldmapIterablethis@mapIterable

请注意,这只是在重新发明 Sequence.map。只需改用即可。mapIterablemap

product很好,但 using 意味着当序列为空时会引发异常。我会用以下命令来写这个:reducefold

fun Sequence<Int>.product() = fold(1, Int::times)

在 中,不是 ,而是 。您可以将其转换为 using asSequencepowerOf(1..exponent)Sequence<Int>IntRangeSequence<Int>

(1..exponent).asSequence().map { x -> this }.product()

另一种方法是 generateSequence 生成 的无限序列,然后 。thistake(exponent)

infix fun Int.powerOf(exponent: Int) =
    generateSequence { this }.take(exponent).product()

也就是说,在这里懒惰地做事并不比仅仅创建一个.使用此方法可以有意义地计算的最大指数是 31(2^31,并且您已经达到了 的最大值 )。数组中的 31 个整数并不多。IntArray(exponent) { this }Int

评论

0赞 ArekBulski 11/8/2023
为了便于论证,我们假设指数是 10 亿。产品将没有意义,但这不是重点。然后,数组将占用大量内存。如果这些 int 被装箱,那就更糟了,对吧?编辑啊 IntArray 是一个原始数组,请忽略。