2015-07-22 23 views
2

我有一个结构类似于以下树添加到树中的节点:使用postwalk

(def tree 
    [:ul 
    [:li 
    [:input]] 
    [:li 
    [:input]]]) 

我想插入一个[:按钮]每个后[:输入]:

[:ul 
[:li 
    [:input] 
    [:button]] 
[:li 
    [:input] 
    [:button]] 

我写了下面的代码:

(postwalk 
    (fn [x] 
    (if (and (vector? x) (= :input (first x))) 
     (list x [:button]) 
     x)) 
    tree) 

主要生产:

[:ul 
[:li 
    ([:input] [:button])] 
[:li 
    ([:input] [:button])]] 

这是几乎我想要的东西,除了[:输入]和[:键]向量 现在在列表中。

有没有一种习惯的方式来“插入”两个节点,而不必将它们放在一起列表?

(注:打嗝产生与目前的结果所需的标记,但我想避免重挫我的树。)

回答

5

你无法回避的列表(或载体),如果你这样做了,在更换[:input]级别,因为fn的结果将永远是单个元素。你需要列表来包含这两个元素。

一个替代方案是在[:li]水平做替换:

(postwalk 
    (fn [x] 
    (if (and (vector? x) (= :li (first x)) (= :input (ffirst (rest x)))) 
     (conj x [:button]) 
     x)) 
    tree) 

,如果你真的想避免的名单那是。正如你所说的,在打嗝的情况下,它可以正常工作。我不会为此担心。