2013-06-27 5 views
7
(def threads 
    {:values 
    [{:_id "t1" 
    :u {:uid 1} 
    :members {:values [{:uid 1} {:uid 2}]} 
    :messages {:values 
       [{:_id "m1" :u {:uid 1}} 
       {:_id "m2" :u {:uid 2}}]}} 
    {:_id "t2" 
    :u {:uid 12} 
    :members {:values [{:uid 11} {:uid 12}]} 
    :messages {:values 
       [{:_id "m3" :u {:uid 13}} 
       {:_id "m4" :u {:uid 12}}]}}]}) 

कुंजी के लिए सभी मूल्यों पता लगाने के लिए की जरूरत है: [1 2 11 12 13] किसी भी वैश्विक का उपयोग किए बिना uid इस मामले जवाब में लौटना चाहिए बाइंडिंग। नेस्टेड संरचना के किसी भी स्तर के लिए समाधान पैमाने की आवश्यकता है।clojure में एक आंतरिक संरचना में किसी कुंजी के लिए सभी मूल्यों को प्राप्त करने के लिए कैसे

धन्यवाद

उत्तर

9

इस पेड़-सेक और फिल्टर, या बाद टहलने के साथ साथ किया जा सकता। दोनों appraoches मुझे दिलचस्प हैं:

पेड़-सेक:

user> (map :uid 
      (filter #(if (and (map? %) (:uid %)) true false) 
        (tree-seq #(or (map? %) (vector? %)) identity threads))) 
(1 2 1 1 2 13 12 12 11 12) 

कौन सा बेहतर लग रहा है जब ->> के साथ बाहर पिरोया (और सेट और vec साथ dups दूर करने के लिए)

user> (->> (tree-seq #(or (map? %) (vector? %)) identity threads) 
      (filter #(if (and (map? %) (:uid %)) true false)) 
      (map :uid) 
      set 
      vec)         
[1 2 11 12 13] 

या postwalk साथ :

user> (let [results (atom [])] 
     (clojure.walk/postwalk 
      #(do (if-let [uid (:uid %)] (swap! results conj uid)) %) 
      threads) 
     @results) 
[1 2 1 1 2 13 12 12 11 12] 

यह संरचना को एक समारोह के साथ चलता है, यदि स्ट्र ucture में एक कुंजी नाम है: uid, इसे स्थानीय परमाणु में जोड़ता है। फिर अंत में परमाणु की जमा सामग्री लौटें। यह आपके उदाहरण से थोड़ा अलग है क्योंकि यह डुप्लीकेट जमा करता है। आप उन्हें कुशलतापूर्वक तो खत्म करने एक वेक्टर के बजाय संचायक के रूप में एक सेट का उपयोग करें, तो अंत में एक बार एक सदिश में बदल करना चाहते हैं (अपने उदाहरण एक सदिश में परिणाम है)

user> (let [results (atom #{})] 
     (clojure.walk/postwalk 
      #(do (if-let [uid (:uid %)] (swap! results conj uid)) %) 
      threads) 
     (vec @results)) 
[1 2 11 12 13] 
+0

धन्यवाद आर्थर। मुझे पेड़-सीक उत्तर अधिक पसंद है। जैसा कि मैंने क्लोजर का उपयोग करना शुरू कर दिया है - मुझे डेटा-इन-> डेटा-आउट परमाणु दृष्टिकोण से अधिक पसंद है। आज कुछ नया सीख लिया - बहुत बहुत धन्यवाद :) –

+1

'(नक्शा: यूआईडी (फ़िल्टर # (अगर (और (नक्शा?%) (: Uid%)) सच झूठा) coll)) 'को केवल' के साथ प्रतिस्थापित किया जा सकता है (रखें: यूआईडी कॉल) '। – amalloy

+0

ओह, फैंसी :) मुझे यह बहुत बेहतर दिखना पसंद है। –

संबंधित मुद्दे

 संबंधित मुद्दे