Clojure从循环返回值

Clojure从循环返回值,clojure,Clojure,我想计算交点。这很好,但我想将点存储在函数应该返回的向量中 这是我的密码: (defn intersections [polygon line] (let [[p1 p2] line polypoints (conj polygon (first polygon))] (doseq [x (range (- (count polypoints) 1))] (println (intersect p1 p2 (nth polypoints x)

我想计算交点。这很好,但我想将点存储在函数应该返回的向量中

这是我的密码:


(defn intersections
  [polygon line]

  (let [[p1 p2] line
        polypoints (conj polygon (first polygon))]

    (doseq [x (range (- (count polypoints) 1))]

      (println  (intersect p1 p2 (nth polypoints x) (nth polypoints (+ x 1))))
)))


我想将结果添加到应该返回的新向量中,而不是
println
。如何更改它?

您需要为循环使用
doseq
函数仅用于副作用,始终返回
nil
。例如:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test))

(defn intersect-1
  [numbers]
  (let [data-vec (vec numbers)]
    (vec
      (for [i (range (dec (count numbers)))]
        {:start (nth data-vec i)
         :stop  (nth data-vec (inc i))}))))
从单元测试中可以看出,上述方法是有效的:

(dotest
  (is= (intersect-1 (range 5))
    [{:start 0, :stop 1}
     {:start 1, :stop 2}
     {:start 2, :stop 3}
     {:start 3, :stop 4}])
但是,在Clojure中这样写更为自然:

(defn intersect-2
  [numbers]
  (let [pairs (partition 2 1 numbers)]
    (vec
      (for [[start stop] pairs]
        {:start start :stop  stop} ))))
同样的结果

  (is= (intersect-2 (range 5))
    [{:start 0, :stop 1}
     {:start 1, :stop 2}
     {:start 2, :stop 3}
     {:start 3, :stop 4}]))
您可以获得更多的详细信息(包括一个大的文档列表!)。尤其要看Clojure的备忘单


侧注:在两个版本中,
vec
都是可选的。这只是将答案强制放入Clojure向量(而不是“lazy seq”),这更容易在示例和单元测试中剪切和粘贴。

您需要使用
for
循环。
doseq
函数仅用于副作用,始终返回
nil
。例如:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test))

(defn intersect-1
  [numbers]
  (let [data-vec (vec numbers)]
    (vec
      (for [i (range (dec (count numbers)))]
        {:start (nth data-vec i)
         :stop  (nth data-vec (inc i))}))))
从单元测试中可以看出,上述方法是有效的:

(dotest
  (is= (intersect-1 (range 5))
    [{:start 0, :stop 1}
     {:start 1, :stop 2}
     {:start 2, :stop 3}
     {:start 3, :stop 4}])
但是,在Clojure中这样写更为自然:

(defn intersect-2
  [numbers]
  (let [pairs (partition 2 1 numbers)]
    (vec
      (for [[start stop] pairs]
        {:start start :stop  stop} ))))
同样的结果

  (is= (intersect-2 (range 5))
    [{:start 0, :stop 1}
     {:start 1, :stop 2}
     {:start 2, :stop 3}
     {:start 3, :stop 4}]))
您可以获得更多的详细信息(包括一个大的文档列表!)。尤其要看Clojure的备忘单


侧注:在两个版本中,
vec
都是可选的。这只是将答案强制放入Clojure向量(而不是“lazy seq”),这更容易在示例和单元测试中剪切和粘贴。

与for循环相比,
映射更为惯用

(defn intersections
  [polygon line]
  (let [[p1 p2] line]
    (vec (map (fn [pp1 pp2] (intersect p1 p2 pp1 pp2)) polygon (cdr polygon)))))
或:


与for循环相比,
映射
更为惯用

(defn intersections
  [polygon line]
  (let [[p1 p2] line]
    (vec (map (fn [pp1 pp2] (intersect p1 p2 pp1 pp2)) polygon (cdr polygon)))))
或:


谢谢你详细的回答。它帮助我解决了我的问题,并使我对Clojure有了更多的了解。谢谢你详细的回答。它帮助我解决了我的问题,让我更不受Clojure的影响。