我有一个匿名函数,带有一个以持久性数组map作为参数(还有一个用于累积结果的map)的reduce。因此,在缩减期间,lambda函数将在所有键/值对上进行迭代。但是我需要根据条件停止整个还原过程。问题在于,“减少”仅针对当前键终止,并不能阻止继续进行后续操作,并且结果会像我没有满足条件那样被累积!
(defn my-func [my-map src]
(reduce (fn [acc [k v]] ; on cond I want to stop look on [k v] pairs and exit reuction and even my-func !!!
(assoc acc (key value))) (empty src) my-map))
我期望的是一种尽早终止的方法,例如说一个空值。
答案 0 :(得分:2)
减少了“作品”:
(reduce #(if (< %2 100) %2 (reduced :one-hundred)) (range 1 100))
99
(reduce #(if (< %2 100) %2 (reduced :one-hundred)) (range 1 101))
:one-hundred
但是,地图或集合的迭代顺序可能不是您期望的:
(reduce #(if (< %2 1000) (inc %1) (reduced %1)) 0 (apply hash-set (range 1000)))
1000
(reduce #(if (< %2 999) (inc %1) (reduced %1)) 0 (apply hash-set (range 1000)))
510
(reduce #(if (< %2 998) (inc %1) (reduced %1)) 0 (apply hash-set (range 1000)))
157
通过一些简化尝试匹配您拥有的表单。此版本将复制输入映射,除非键:a缩小为空映射时不存在。
(defn my-func [m]
(reduce (fn [acc [k v]]
(if (= k :a) (reduced {}) ;; if cond return empty
(assoc acc k v))) {} m))
(my-func {:b 4 :c 7})
;; =>
{:b 4, :c 7}
(my-func {:a 2 :d 6})
;; =>
{}
答案 1 :(得分:0)
如果我正确理解您的问题:如果您的地图具有满足条件的键和/或值,则您不希望处理该地图,而只是返回一些您早已退出的标记。您可以为此使用循环:
(defn my-func [my-map]
(loop [m my-map]
(if-let [[k v] (first m)]
(if (= v 4) ;; your condition for exit-early
:four ;; return your exit-early marker
(recur (rest m)))
my-map))) ;; you looped throught the whole map without exit-early
(my-func {:a 1 :b 2 :c 3 :d 4 :e 5})
您甚至可以传入exit-early-predicate和一个标记作为参数:
(defn my-func [my-map kv-exit-pred marker]
(loop [m my-map]
(if-let [[k v] (first m)]
(if (kv-exit-pred k v)
marker
(recur (rest m)))
my-map)))
(my-func {:a 1 :b 2 :c 3 :d 4 :e 5} #(= %2 3) :three)
在这两种情况下,如果您不提早退房,那么只需返回原始地图即可(因为这是您的reduce函数在实践中所做的事情)。