aysylu / loom

Graph library for Clojure. Mailing list https://groups.google.com/forum/#!forum/loom-clj
http://aysy.lu/loom/
886 stars 108 forks source link

remove-nodes does not prune attributes #93

Open cemerick opened 7 years ago

cemerick commented 7 years ago
(require '[loom.graph :as g]
         '[loom.attr :as ga])

(-> (g/digraph {:a [:b]})
    (ga/add-attr [:a :b] :foo :bar)
    (g/remove-nodes :a)
    (ga/attrs [:a :b]))
=> {:foo :bar}

Is this intentional, or an oversight? I can believe either, though I'd prefer the latter to be the case.

cemerick commented 7 years ago

A quickie implementation of attribute pruning, if anyone needs it:

(defn- prune-attrs
  "Prunes the attributes of a graph to refer only to nodes in the [keep] set.

   e.g. (update (g/subgraph g reachable) :attrs (partial prune-attrs reachable))"
  [keep attrs]
  (reduce
    (fn [attrs [n nattrs]]
      (if-not (keep n)
        (dissoc attrs n)
        (let [edge-attrs (::ga/edge-attrs nattrs)
              edge-attrs' (reduce
                            #(if (keep %2) % (dissoc % %2))
                            edge-attrs
                            (keys edge-attrs))]
          (cond
            (identical? edge-attrs edge-attrs') attrs
            (empty? edge-attrs') (update attrs n dissoc ::ga/edge-attrs)
            :default (assoc-in attrs [n ::ga/edge-attrs] edge-attrs')))))
    attrs
    attrs))

Perhaps there's a fancier-faster way, but this is a workaround for me for now.