Basically, I have a vector of sets. I'd like to merge the sets based on a criteria (you can see this criteria in the if statement). More than two sets may be merged. Here is an example data set:
[{:name "corner", :matched-shape "corner", :direction :e, :rotation 1}
{:name "corner", :matched-shape "corner", :direction :e, :rotation 2}
{:name "corner", :matched-shape "corner", :direction :s, :rotation 2}
{:name "corner", :matched-shape "corner", :direction :s, :rotation 3}
{:name "corner", :matched-shape "pipe", :direction :s, :rotation 0}
{:name "corner", :matched-shape "pipe", :direction :e, :rotation 1}
{:name "corner", :matched-shape "pipe", :direction :s, :rotation 2}
{:name "corner", :matched-shape "pipe", :direction :e, :rotation 3}
{:name "corner", :matched-shape "cross", :direction :e, :rotation 0}
{:name "corner", :matched-shape "cross", :direction :s, :rotation 0}
{:name "corner", :matched-shape "cross", :direction :e, :rotation 1}
{:name "corner", :matched-shape "cross", :direction :s, :rotation 1}]
I have tried dozens of solutions but none of them work. Here is my code:
(defn merge-symmetry-table [symmetry-table]
(filter #(if-not (nil? %) %)
(loop [[x y & remaining] symmetry-table result []]
(if-not (empty? y)
(if (and (= (:name x) (:name y))
(= (:direction x) (:direction y)))
(recur [(concat-symmetries x y) remaining] result)
(recur [conj y remaining] [result x]))
(conj result x)))))
and my output as of now:
([]
{:name "corner", :direction :e, :matched-shapes ["corner" 1 "corner" 2]}
{:name nil, :direction nil, :matched-shapes [[nil nil nil nil] nil nil]})
I'm sure there is a nicer way to do this, but I would like to know what is exactly wrong with my code. I've gone it over literally fifty times and I cannot understand what is wrong. Thank you for your help.
I'm not sure if I am allowed to express dissatisfaction here (and I do not wish to bother anyone), but I have had absolutely immense difficulty dealing with data in this programming language. Admittedly, this is my first project in this language and I'm mostly a self-taught coder. But nesting vectors inside vectors and using just "keymaps" has made it an absolute nightmare trying to get anything done let alone organize data in a cohesive manner. I probably rewrite my functions at least ten times just to get them to return what I want. There must be something I'm missing.
You probably want to use either partition-by
:
(defn merge-symmetry-table [data]
(->> data
(partition-by (juxt :name :direction))
(map (partial apply concat-symmetries))))
or group-by
:
(defn merge-symmetry-table [data]
(->> data
(group-by (juxt :name :direction))
vals
(map (partial apply concat-symmetries))))