我正试图使用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
?
回答我自己的问题:
下面是工作代码:(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}
]))))
这段代码允许我从映射中提取值,但只关注真正重要的键。其余键值对将被忽略。