Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 遍历向量树_Clojure_Tree_Multimethod_Hiccup - Fatal编程技术网

Clojure 遍历向量树

Clojure 遍历向量树,clojure,tree,multimethod,hiccup,Clojure,Tree,Multimethod,Hiccup,我想遍历表示hiccup数据结构的向量树: [:div {:class "special"} [:btn-grp '("Hello" "Hi")]] 然后我想分派向量的关键字,如果为关键字定义了multimemethod,那么它将返回另一组向量,这将替换原始标记 例如,上述结构将转换为: [:div {:class "special"} [:div [:button "Hello"] [:button "Hi"]]] 自定义多重方法将接收列表(“hello”“hi”)作为参数。然后它将返回

我想遍历表示hiccup数据结构的向量树:

[:div {:class "special"} [:btn-grp '("Hello" "Hi")]] 
然后我想分派向量的关键字,如果为关键字定义了multimemethod,那么它将返回另一组向量,这将替换原始标记

例如,上述结构将转换为:

[:div {:class "special"} [:div [:button "Hello"] [:button "Hi"]]]
自定义多重方法将接收列表(“hello”“hi”)作为参数。然后它将返回包含按钮的div

如何编写一个函数,遍历向量并将表单中的所有其他内容作为参数分派到关键字上,然后用返回的表单替换当前表单

(ns customtags
  (:require [clojure.walk :as walk]))

(def customtags (atom {}))

(defn add-custom-tag [tag f]
  (swap! customtags assoc tag f))

(defn try-transform [[tag & params :as coll]]
  (if-let [f (get @customtags tag)]
    (apply f params)
    coll))

(defmacro defcustomtag [tag params & body]
  `(add-custom-tag ~tag (fn ~params ~@body)))

(defn apply-custom-tags [coll]
  (walk/prewalk
    (fn [x]
      (if (vector? x)
        (try-transform x)
        x)) coll))
使用它:

(require '[customtags :as ct])
(ct/defcustomtag :btn-grp [& coll] (into [:div] (map (fn [x] [:button x]) coll)))
(ct/defcustomtag :button [name] [:input {:type "button" :id name}])

(def data [:div {:class "special"} [:btn-grp "Hello" "Hi"]])

(ct/apply-custom-tags data)
[:div {:class "special"} [:div [:input {:type "button", :id "Hello"}] [:input {:type "button", :id "Hi"}]]]

丹尼,谢谢你的回复。然而,您为什么说将整个树表示为数据结构没有价值呢。Hiccup为表带来了价值,正是因为它允许您将HTML树作为向量树进行操作,如果自定义标记也可以以同样的方式呈现,这会有帮助吗?我是本着学习的精神问这个问题的,所以请让我知道你的意见。
customtags
只是一种笨拙的多重方法,
defcustomtag
defmulti
。只需定义一个在向量的第一个元素上分派的multimethod,以及一个
:default
方法就可以了。然后使用
prewalk
进行遍历。我首先尝试了多方法方法,但我发现编写defmethod函数比编写宏方法更麻烦,因为:default情况下需要整个向量,这意味着每个defmethod都必须处理整个向量。当然,您可以编写一个宏来编写defmethod来处理这个问题,但我不认为这会比建议的代码更简洁、更直接。