I am trying to pull data out of a map using Clojure core.logic. This code does as I want it to:
(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"])
However if I add some other elements to the map then it fails to match:
(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}
])))
I understand why matcho
is not working as the maps no longer the same. My quesiton is, how can I change this so that it works again? How do I get it to match on only some of the keys in a map or how can I get it to match whatever random keys a map may have?
EDIT:
I got it to work using patial-map
(thanks to 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}
])))
However I found a note that featurec
should be used instead of partial-map
. My new question: How to change this to use featurec
?
Answering my own question:
Here is the working code:
(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}
]))))
This code allows me to extract values from a map but only paying attention to the keys that are really important. The rest of the key value pairs are ignored.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With