2017-08-15 6 views
2

Comment pourrait-on s'exprimer dans la transformation idiomatique de Clojure?Carte imbriquée à la séquence de tuples représentant les bords dans Clojure

(def m 
    {:a {:b {:c nil 
       :d nil}} 
      :e nil}}) 


(map->edges m) ; => 


([:a :b] [:b :c] [:b :d] [:e nil] [:d nil] [:a :e] [:e nil]) 

Je ne me soucie pas de l'ordre dans lequel les vecteurs apparaissent dans le résultat, de sorte que soit la profondeur première ou à couper le souffle premières stratégies de recherche sont très bien.

+1

FWIW le format d'entrée n'est pas vraiment une très bonne façon de représenter un graphique, puisqu'il n'est pas clair comment les cycles vont fonctionner. Plus typique est quelque chose comme une carte d'adjacence, où les clés sont des nœuds et les valeurs sont des ensembles de nœuds. Pour votre graphe, cela ressemblerait à ''{a # {b e}, b # {c d}}', avec éventuellement des ensembles vides pour c/d/e pour indiquer des noeuds sans bords sortants. Idéalement, je dirais de corriger votre format d'entrée afin que vous n'ayez pas à faire cette étape, mais si vous ne pouvez pas le contrôler, alors les réponses à cette question sont un moyen raisonnable de le post-traiter. – amalloy

Répondre

8

Vous pouvez exprimer en utilisant assez de façon concise for et tree-seq:

(defn map->edges [m] 
    (for [entry m 
     [x m] (tree-seq some? val entry) 
     y (or (keys m) [m])] 
    [x y])) 

Exemple:

(map->edges m) 
;;=> ([:a :b] [:a :e] [:b :c] [:b :d] [:c nil] [:d nil] [:e nil])