Итерация по досрочному прекращению сбора - PullRequest
1 голос
/ 18 апреля 2019

У меня есть редуцирование с анонимной функцией с постоянной картой массива в качестве параметра (и картой для накопления результата).Таким образом, во время сокращения лямбда-функция выполняет итерацию по всем парам ключ / вал.Все же мне нужно остановить весь процесс сокращения при условии.Проблема состоит в том, что «сокращенный» завершается только для клавиши current и не мешает перейти к следующему, а результат будет накапливаться, как если бы я не соответствовал условию!

(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))

То, что я ожидаю, это способ досрочного завершения, скажем, пустое значение как результат.

Ответы [ 2 ]

2 голосов
/ 18 апреля 2019

сокращенных «работ»:

(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

Попытка сопоставить имеющуюся форму с некоторыми упрощениями. Эта версия будет копировать входную карту, если только ключ: не присутствует, когда он будет уменьшен до пустой карты.

(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})
;; =>
{}
0 голосов
/ 22 апреля 2019

Если я правильно понимаю ваш вопрос: если ваша карта имеет ключ и / или значение, которое удовлетворяет условию, вы хотите не обрабатывать карту, а просто вернуть маркер, который вы покинули раньше.Для этого вы можете использовать цикл:

(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})

Вы можете даже передать предикат выхода-ранний и маркер в качестве аргументов:

(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)

В обоих случаях, если вы нене выходите пораньше, затем просто верните исходную карту (как это делает ваша функция на практике).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...