gpt4 book ai didi

clojure - 如何在 Clojure 中映射很少使用的状态?

转载 作者:行者123 更新时间:2023-12-02 13:34:29 26 4
gpt4 key购买 nike

情况如下:我正在转换一系列值。每个值的转换分为许多不同的情况。大多数值是完全相互独立的。然而,有一种特殊情况需要我跟踪到目前为止我遇到了多少特殊情况。在命令式编程中,这非常简单:

int i = 0;
List<String> results = new ArrayList<>();
for (String value : values) {
if (case1(value)) {
results.add(handleCase1(value));
} else if (case2(value)) {
...
} else if (special(value)) {
results.add(handleSpecial(value, i));
i++;
}
}

但是在 Clojure 中我想出的最好的方法是:

(first 
(reduce
(fn [[results i] value]
(cond
(case-1? value) [(conj results (handle-case-1 value)) i]
(case-2? value) ...
(special? value) [(conj results (handle-special value i))
(inc i)]))
[[] 0] values))

考虑到如果没有特殊情况,这将变得非常难看:

(map #(cond 
(case-1? %) (handle-case-1 %)
(case-2? %) ...)
values)

问题是我在缩减过程中手动将序列缝合在一起。此外,大多数情况甚至不关心索引,但仍然必须将其传递给下一个缩减步骤。

这个问题有更干净的解决方案吗?

最佳答案

有时,使用looprecur的代码看起来比使用reduce的等效代码更好。

(loop [[v & more :as vs] values, i 0, res []]
(if-not (seq vs)
res
(cond
(case-1? v) (recur more i (conj res (handle-case-1 v)))
(case-2? v) (recur more i (conj res (handle-case-2 v)))
(special? v) (recur more (inc i) (conj res (handle-special i v))))))

由于似乎有一些需求,这里有一个产生惰性序列的版本。关于过早优化和保持简单的惯例警告适用。

(let [handle (fn handle [[v & more :as vs] i]
(when (seq vs)
(let [[ii res] (cond
(case-1? v) [i (handle-case-1 v)]
(case-2? v) [i (handle-case-2 v)]
(special-case? v) [(inc i) (handle-special i v)])]
(cons res (lazy-seq (handle more ii))))))]
(lazy-seq (handle values 0)))

关于clojure - 如何在 Clojure 中映射很少使用的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44371397/

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