2016-09-02 4 views
1

clojure.zip을 사용하여이 트리를 탐색하고 노드와 그 부모를 인쇄하십시오. 나는 부모를 얻는데 어려움을 겪고있다. 예를 들어, :e의 부모는 :b입니다. 모든 부모를 트리를 통해 걷는 것으로 찾으십시오.

;; 
;;  :a 
;; /\ 
;; :b :c 
;; /\ \ 
;; :d :e :f 
;; 
(def example [:a [:b [:d] [:e]] [:c [:f]]]) 
(def z (zip/vector-zip example)) 
(def locs (take-while (complement zip/end?) (iterate zip/next z))) 

(defn parent-of [loc] 
    (when-let [parent-loc (-> loc zip/up zip/left)] 
    (zip/node parent-loc))) 

(defn visit-all [] 
    (doseq [loc locs] 
    (let [node (zip/node loc)] 
     (when (keyword? node) 
     (println node "has parent" (parent-of loc)))))) 

은 결과입니다

:a has parent nil 
:b has parent :a 
:d has parent :b 
:e has parent [:d] 
:c has parent [:b [:d] [:e]] 
:f has parent :c 

나는 parent-of 기능을 지속적으로 개선 할 수 - 내 옆에 생각이 가장 왼쪽 노드로 이동하는 것입니다. 모든 위치에서 정답을 반환하는 알고리즘이 있습니다. 그러나이 방법은 일반적인 요구 사항에 대한 많은 작업처럼 보입니다.

제가 취해야 할 더 나은 방법이 있습니까?

편집 이 질문은 clojure.walk 또는 Spector하지에 대한 것입니다. 난 clojure.zip을 사용하여 질문에 정의 된대로 부모에게주는 대답을 찾고 있는데, 단순히 loc 위의 키워드입니다. 따라서 locparent-of 인 경우 :f 일 경우 :c을 반환 할 것으로 예상됩니다.

지퍼가 실제로는 더 이상 사용되지 않는다고 말하면 clojure.walk 또는 Spector이 나무를 탐색하기위한 현재 모범 사례 방법이라고 말하면 도움이 될 것입니다.

+0

당신이 구현하고자하는 기능에 대한 샘플 입력과 출력을 제공 할 수 있습니까? – OlegTheCat

+0

[Clojure - path with path]의 가능한 복제본 (http://stackoverflow.com/questions/33594375/clojure-walk-with-path) – nha

답변

2

zip/left을 사용하고 있습니까? 노드의 부모 노드는 노드 바로 위의 노드이며 노드 위에는 노드가 아니며 왼쪽에있는 이유가 있습니다. 제거 만하면됩니다.

+0

엄밀히 말하면'zip/up'은 부모를 제공한다는 것을 알고 있습니다. 그러나 부모는 항상 단지 둘러싸인 벡터 일뿐입니다. 내가 필요한 것은 (나는 믿는다)이 둘러싸는 벡터의 첫 번째 요소이다. 그래서 내 질문에 나는': e'의 부모가 기술적으로': e'의 부모를 기술적으로 말하고 있지만 [: b [: d] [: e]]'라고 말했다. –

+0

노드 레이블 만 필요하고 구조는 필요 없으면'(z/loc (z/up loc))'결과에'first'를 호출하십시오. – amalloy

0

이 내 자신의 대답 :

(defn parent-of [loc] 
    (when-let [parent-loc (-> loc zip/up zip/up first)] 
    (zip/node parent-loc))) 

그것은 모든 경우에 정확한 출력을 제공 :

:a has parent nil 
:b has parent :a 
:d has parent :b 
:e has parent :b 
:c has parent :a 
:f has parent :c 
관련 문제