2016-02-13 58 views
2

我需要通過應用以下兩個規則把以下輸入的輸出:是否可以使用拉鍊操縱嵌套地圖的矢量?

  1. 刪除具有「不」的所有矢量作爲最後一個項目
  2. 刪除每個地圖不具有與至少一個矢量「DS1」作爲最後一個項目
(def input 
    [{:simple1 [:from [:simple1 'ds1]]} 
    {:simple2 [:from-any [[:simple2 'nope] [:simple2 'ds1]]]} 
    {:walk1 [:from [:sub1 :sub2 'ds1]]} 
    {:unaffected [:from [:unaffected 'nope]]} 
    {:replaced-with-nil [:from [:the-original 'ds1]]} 
    {:concat1 [:concat [[:simple1 'ds1] [:simple2 'ds1]]]} 
    {:lookup-word [:lookup [:word 'word :word 'ds1]]}]) 

(def output 
    [{:simple1 [:from [:simple1 'ds1]]} 
    {:simple2 [:from-any [[:simple2 'ds1]]]} 
    {:walk1 [:from [:sub1 :sub2 'ds1]]} 
    {:replaced-with-nil [:from [:the-original 'ds1]]} 
    {:concat1 [:concat [[:simple1 'ds1] [:simple2 'ds1]]]} 
    {:lookup-word [:lookup [:word 'word :word 'ds1]]}]) 

我在想,如果執行這個轉變是可能的拉鍊?

+1

您可以加入一些細節到您的文章,以什麼導致你考慮​​拉鍊的方式來解決這個問題? –

+1

簡短的回答是肯定的。 –

+1

我很驚訝沒有人提到這個問題實際上並不是**走向矢量值的地圖矢量**。示例數據中的所有地圖都有一個關鍵字,而關鍵字與所涉及的過濾無關。因此,向量中的每個映射(迭代)都可以通過一個謂詞進行饋送,該謂詞**走向矢量矢量,任意嵌套**。我會建議編輯問題並更新標題。 – muhuk

回答

0

我建議clojure.walk而不是爲這種樹一般改造。它可能需要一些擺弄才能獲得替換功能,但它與任何嵌套的Clojure數據結構都能很好地協作,在基於拉鍊的方法中,AFAIK可能更具挑戰性。

我們正在期待收縮我們的樹,所以postwalk是我去這裏。它需要一個函數f和一個樹根並遍歷樹,用(f leaf)替換每個葉子值,然後是他們的父母和他們的父母等,直到最終替換根。 (prewalk相似,但來自根到葉收益,所以它通常是更自然,當你通過拆分分支機構越來越多的樹。)
這裏的策略是以某種方式構建修剪符合我們的刪除條件的任何分支功能,但返回任何其他值不變。

(ns shrink-tree 
    (:require [clojure.walk :refer [postwalk]])) 

(letfn[(rule-1 [node] 
     (and (vector? node) 
       (= 'nope (last node)))) 
     (rule-2 [node] 
     (and 
      (map? node) 
      (not-any? #(and (vector? %) (= 'ds1 (last %))) 
        (tree-seq vector? seq (-> node vals first))))) 
     (remove-marked [node] 
         (if (coll? node) 
         (into (empty node) (remove (some-fn rule-1 rule-2) node)) 
         node))] 
    (= output (postwalk remove-marked input))) 
;; => true 

這裏FNS rule-1rule-2嘗試把你的規則轉化爲謂詞和remove-marked

  1. 如果一個節點是一個集合,返回相同的集合,少的任何成員,其rule1rule2回報當與該成員打電話時真誠。要同時檢查任何一個,我們將謂詞與some-fn結合起來。
  2. 否則返回相同的節點。這就是我們如何保持像'ds1:from-any這樣的值。
0

你也可以考慮看specter。它支持這些類型的轉換,允許您選擇和轉換任意複雜的結構。