2013-01-04 37 views
5

我想用Clojure core.logic從地圖中提取數據。此代碼,因爲我希望它:從Clojure core.logic提取地圖的元素

(run 10 [q] 
    (fresh [?id ?type ?name] 
     (membero ?type [:t2 :t1]) 
     (== q [?id ?name]) 
     (membero {:id ?id :type ?type :name ?name} 
      [ 
      {:id 1 :type :t1 :name "one"} 
      {:id 2 :type :t2 :name "two"} 
      ]))) 
=> ([2 "two"] [1 "one"]) 

但是如果我加入一些其他元素,地圖則無法匹配:

(run 10 [q] 
    (fresh [?id ?type ?name] 
     (membero ?type [:t2 :t1]) 
     (== q [?id ?name]) 
     (membero {:id ?id :type ?type :name ?name} 
      [ 
      {:id 1 :type :t1 :name "one" :other1 :o1} 
      {:id 2 :type :t2 :name "two" :other2 :o2} 
      ]))) 

我明白爲什麼matcho不工作的地圖沒有更長的一樣。我的問題是,我怎樣才能改變這一點,以便它再次運作?我如何才能使它匹配地圖上的某些鍵,或者如何使它匹配地圖可能具有的任何隨機鍵?

編輯:

我把它用patial-map工作(感謝https://github.com/clojure/core.logic/pull/10

(run 10 [q] 
    (fresh [?id ?type ?name] 
      (membero ?type [:t2 :t1]) 
      (== q [?id ?name]) 
      (membero (partial-map {:id ?id :type ?type :name ?name}) 
        [ 
        {:id 1 :type :t1 :name "one" :other1 :o2} 
        {:id 2 :type :t2 :name "two" :other2 :o1} 
        ]))) 

不過,我發現一張紙條,上面featurec應該用來代替partial-map。我的新問題:如何改變這個使用featurec

+0

我添加了我使用的測試代碼的要點:https://gist.github.com/4454548 –

回答

6

回答我的問題:

這裏是工作代碼:

(run 10 [q] 
    (fresh [?id ?type ?name ?pm] 
      (membero ?type [:t2 :t1]) 
      (== q [?id ?name]) 
      (featurec ?pm {:id ?id :type ?type :name ?name}) 
      (membero ?pm 
        [ 
        {:id 1 :type :t1 :name "one" :other1 :o2} 
        {:id 2 :type :t2 :name "two" :other2 :o1 :another :ao2} 
        {:id 3 :type :t3 :name "three" :other2 :o1 :another :ao1} 
        ])))) 

此代碼可以讓我來提取地圖值,而僅關注那些真正重要的關鍵。其餘的鍵值對被忽略。