Clojure doseq嵌套循环以创建新集

时间:2014-07-04 04:18:12

标签: loops clojure

在Clojure中,我希望能够将一组中的所有数字相乘并将它们全部添加到一个新的集合中以返回。

=>(multiply-all #{ 1 2 3})

#{1 4 6 3 2 9}

这是我的实施:

(defn multiply-all [num-set]
  (loop [new-set num-set
         cur-set num-set]
       (if (= 0 (count cur-set))  new-set
       (recur (into new-set (map #(* (first cur-set) %) num-set)) (rest cur-set)))))

有没有办法在不使用瞬态的情况下使用doseq来做到这一点。像这样:

(let [s #{ 1 2 3}]
 (doseq [outer s]
   (doseq [inner s]
     (let [multiplied (* outer inner)]
      (println (conj s multiplied))
      ))))

我对任何有关更清洁方式的建议感兴趣。

--- ---- EDIT 这是使用reduce的另一种方式:

(defn multiply-all2 [num-set]
  (let [step (fn [[ result ] mult]
           [(into result (map #(* mult %) num-set))])]
    (first (reduce step [num-set] num-set))))

2 个答案:

答案 0 :(得分:5)

doseq是副作用。您可能希望改为使用for

user=> (set (for [a #{1 2 3} 
                  b #{1 2 3}] 
              (* a b)))
#{1 4 6 3 2 9}

答案 1 :(得分:2)

(defn multiply-all [s]
  (set (mapcat #(map * s (repeat %)) s)))