2

Lisp/Clojure で書くコードの行数を減らすことが私の強迫観念になりました。次のコード (基本的に深さ優先検索) を短くしようとしています。

(defn find-node  [nodeid in-node]
  (if (= nodeid (:id in-node))
    in-node
    (loop [node nil activities (:activities in-node)]
      (if (or (empty? activities) (not (nil? node)))
        node
        (recur (find-node nodeid (first activities)) (rest activities))))))

(defn find-node-in-graph [nodeid node activities]
  (if (empty? activities)
    node
    (recur nodeid (find-node nodeid (first activities)) (rest activities))))

(defrecord Graph [id name activities])
(defrecord Node [id name activities])

「活動」はリストです

4

1 に答える 1

3

1行だけですが、これは不正行為かもしれません;)

(def tree {:id 1 :children [{:id 2 :children [{:id 3}]} {:id 4}]})

core> (filter #(= 3 (:id %)) (tree-seq :children :children tree)) 
({:id 3}) 

core> (filter #(= 2 (:id %)) (tree-seq :children :children tree))
({:children [{:id 3}], :id 2})

質問の本来の意図に関するいくつかのポイント:

  • loop/recer は多くの場合、最もコンパクトな形式ではありません。通常、mapまたはで記述できます。doseq
  • if/recur は、多くの場合、への呼び出しに置き換えることができますfilter
  • 特定の要件のためにこのようなものを本当に書く必要があると思われる場合は、多くの場合、zipperを使用すると問題がよりエレガントに解決されます。
于 2013-08-15T00:13:12.263 に答える