gpt4 book ai didi

Clojure 惰性序列 : Equivalents in Kotlin

转载 作者:行者123 更新时间:2023-12-05 00:47:51 27 4
gpt4 key购买 nike

Clojure 为 提供方法懒惰评估 (无限)序列中的值。有了这个,值只会在它们被实际消耗时计算。

一个重复元素的无限序列示例:

(take 3 (repeat "Hello StackOverflow")) 
//=> ("Hello StackOverflow" "Hello StackOverflow" "Hello StackOverflow")

使用 take有助于只消耗我们想要的序列中尽可能多的元素。没有它,一个 OutOfMemoryError会很快终止进程。

无限序列的另一个示例如下:
(take 5 (iterate inc 1)) 
//(1 2 3 4 5)

或者提供阶乘函数的更高级序列:
((defn factorial [n]
(apply * (take n (iterate inc 1)))) 5)

Kotlin 是否提供类似的序列?他们看起来怎么样?

我自己回答了这个问题,以便在这里记录知识。根据 Can I answer my own question? 这很好

最佳答案

在 Kotlin 中,我们还可以使用 Sequences 来使用惰性求值, 也。为了创建一个序列,我们可以使用 generateSequence (无论是否提供 seed

fun <T : Any> generateSequence(
seed: T?,
nextFunction: (T) -> T?
): Sequence<T> (source)

Returns a sequence defined by the starting value seed and the function nextFunction, which is invoked to calculate the next value based on the previous one on each iteration.



下面将展示一些比较 Clojure 和 Kotlin 序列的示例。

1.一个简单的 take从一个静态值的无限序列

Clojure
(take 3 (repeat "Hello StackOverflow")) 

Kotlin
generateSequence { "Hello StackOverflow" }.take(3).toList()

这些非常相似。在 Clojure 中,我们可以使用 repeat而在 Kotlin 中,它只是 generateSequence具有将永远产生的静态值。在这两种情况下, take用于定义我们想要计算的元素数量。

注意:在 Kotlin 中,我们将结果序列转换为带有 toList() 的列表

2.一个简单的 take来自动态值的无限序列

Clojure
(take 5 (iterate inc 1))

Kotlin
generateSequence(1) { it.inc() }.take(5).toList()

这个例子有点不同,因为序列无限地产生前一个值的增量。 Kotlin generateSequence可以使用种子(此处: 1 )和 nextFunction 调用(增加先前的值)。

3. 列表中值的循环重复

Clojure
(take 5 (drop 2 (cycle [:first :second :third ])))
// (:third :first :second :third :first)

Kotlin
listOf("first", "second", "third").let { elements ->
generateSequence(0) {
(it + 1) % elements.size
}.map(elements::get)
}.drop(2).take(5).toList()

在这个例子中,我们循环重复列表的值,去掉前两个元素,然后取 5。在 Kotlin 中它很冗长,因为从列表中重复元素并不简单。为了修复它,一个简单的扩展函数使相关代码更具可读性:
fun <T> List<T>.cyclicSequence() = generateSequence(0) {
(it + 1) % this.size
}.map(::get)

listOf("first", "second", "third").cyclicSequence().drop(2).take(5).toList()

4. 阶乘

最后但并非最不重要的一点,让我们看看如何使用 Kotlin 序列解决阶乘问题。首先,让我们回顾一下 Clojure 版本:

Clojure
(defn factorial [n]
(apply * (take n (iterate inc 1))))

我们从一个序列中取 n 个值,该序列产生一个从 1 开始的递增数字,并在 apply 的帮助下累加它们。 .

Kotlin
fun factorial(n: Int) = generateSequence(1) { it.inc() }.take(n).fold(1) { v1, v2 ->
v1 * v2
}

Kotlin 提供 fold 这让我们很容易累积这些值。

关于Clojure 惰性序列 : Equivalents in Kotlin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50748599/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com