gpt4 book ai didi

clojure - 在 Clojure 中一次执行多次归约

转载 作者:行者123 更新时间:2023-12-01 13:45:54 25 4
gpt4 key购买 nike

在 Clojure 中,我想找到多次减少的结果,同时只使用一次序列。在 Java 中,我会执行以下操作:

double min = Double.MIN_VALUE;
double max = Double.MAX_VALUE;
for (Item item : items) {
double price = item.getPrice();
if (price > min) {
min = price;
}

if (price < max) {
max = price;
}
}

在 Clojure 中,我可以通过使用循环和递归来做很多相同的事情,但它不是很可组合 - 我想做一些让您根据需要添加其他聚合函数的事情。

我编写了以下函数来执行此操作:
(defn reduce-multi
"Given a sequence of fns and a coll, returns a vector of the result of each fn
when reduced over the coll."
[fns coll]
(let [n (count fns)
r (rest coll)
initial-v (transient (into [] (repeat n (first coll))))
fns (into [] fns)
reduction-fn
(fn [v x]
(loop [v-current v, i 0]
(let [y (nth v-current i)
f (nth fns i)
v-new (assoc! v-current i (f y x))]
(if (= i (- n 1))
v-new
(recur v-new (inc i))))))]
(persistent! (reduce reduction-fn initial-v r))))

这可以通过以下方式使用:
(reduce-multi [max min] [4 3 6 7 0 1 8 2 5 9])
=> [9 0]

我很欣赏它没有以最惯用的方式实现,但主要问题是它的速度大约是一次减少一个的 10 倍。这对于在 seq 执行大量 IO 的情况下执行大量缩减可能很有用,但肯定这可能会更好。

现有的 Clojure 库中有什么东西可以满足我的需求吗?如果没有,我的功能哪里出错了?

最佳答案

这就是我要做的:只需将此任务委托(delegate)给核心 reduce函数,像这样:

(defn multi-reduce
([fs accs xs] (reduce (fn [accs x] (doall (map #(%1 %2 x) fs accs)))
accs xs))
([fs xs] (when (seq xs)
(multi-reduce fs (repeat (count fs) (first xs))
(rest xs)))))

在回复中:
user> (multi-reduce [+ * min max] (range 1 10))
(45 362880 1 9)

user> (multi-reduce [+ * min max] [10])
(10 10 10 10)

user> (multi-reduce [+ * min max] [])
nil

user> (multi-reduce [+ * min max] [1 1 1000 0] [])
[1 1 1000 0]

user> (multi-reduce [+ * min max] [1 1 1000 0] [1])
(2 1 1 1)

user> (multi-reduce [+ * min max] [1 1 1000 0] (range 1 10))
(46 362880 1 9)

user> (multi-reduce [max min] (range 1000000))
(999999 0)

关于clojure - 在 Clojure 中一次执行多次归约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36270165/

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