ClojureScript中的漂亮嵌套哈希映射

时间:2016-05-06 10:54:08

标签: clojure clojurescript

在ClojureScript中是否有一种方便的方法可以以整个树形结构立即可见的方式打印嵌套的哈希图。

例如像这样的地图

(def my-map {:a {:b 1 :c 9} :b {:d 8 :e {:f 2 :g 3 :h 4}} :c 10})

应该像这样打印:

{:a {:b 1
     :c 9}
 :b {:d 8
     :e {:f 2
         :g 3
         :h 4}}
 :c 10}

编辑:地图中可能还有矢量。用例只是在开发过程中检查更大的数据结构。

2 个答案:

答案 0 :(得分:1)

没有内置的方法可以做到这一点。您可以使用cljs.pprint并将cljs.pprint/*print-right-margin*设置为较低值来接近您想要的内容。

我建议您查看一个小型库shodan,它提供了非常有用的inspect功能:

(require '[shodan.inspection :refer [inspect]])

(inspect {:aaaaaa 1
          :bbbbbb {:ccc 2
                   :dddddd [1 2 3 4 5]}})

它不会在您的CLJS REPL中打印任何内容,但会在您的浏览器控制台中提供方便的视图:

enter image description here

您可以折叠和展开嵌套数据结构 - 它基本上可以满足您的要求。

答案 1 :(得分:0)

作为个人挑战,我写了以下代码:

(enable-console-print!)
(def atomic? (complement coll?))
(def padding #(apply str (repeat % " ")))
(def tabulate #(apply str (repeat % "\t")))
(def strcat #(->> (apply concat %&) (apply str)))
(defn my-max-key [x] (if (empty? x) [""] (apply (partial max-key count) x)))
(defn longest-key [m] (->> m keys (filter atomic?) (map str) my-max-key))
(def length (comp count str))
(def not-map? (complement map?))
(def nested? #(some coll? %))
(def join #(apply str (interpose % %2)))
(def join-lines (partial join "\n"))
(defn has-atomic? [coll] (some atomic? coll))
(defn diff-key-lengths [key1 key2] (- (length key1) (length key2)))
(defn convert
  ([thing] (convert -1 thing))
  ([depth thing]
   (defn convert-items []
     (defn convert-seq []
       (conj []
             (map (partial convert (inc depth)) thing)
             ""))
     (defn string-horizontally [[key value]]
       (str (tabulate (inc depth))
            key
            (padding (diff-key-lengths (longest-key thing) key))
            " → "
            value))
     (defn string-vertically [[key value]]
       (str (convert (inc depth) key) "\n"
            (convert (+ 2 depth) "↓") "\n"
            (convert (inc depth) value) "\n"))
     (defn convert-kv [[key value]]
       (if (nested? [key value])
           (string-vertically [key value])
           (string-horizontally [key value])))
     (cond (atomic? thing)
           [(str (tabulate depth) thing)]

           (not-map? thing)
           (convert-seq)

           (map? thing)
           (map convert-kv thing)))
   (->>  (convert-items) flatten join-lines)))

(def sample-input [["the first thing in this nested vector"]
                   {{"this is a key in a nested map"
                    "that points to me!!!"}
                   {"and that entire map points to this map!!!"
                    "cool!!!"
                    "but it gets cooler cause..."
                    "the value's line up!!!"}}])
(->> sample-input convert println)

终端输出是(psst ...地图中的值确实排成一行,但我不认为chrome使用等宽字体!): chrome screenshot of index.html