2
votes

I'm relatively new to clojure and I wonder what is a good solution to the following problem.

I have two sets of symbols, say:

v1:

q w e r

v2:

a s d f

and they are used to build a third set

A:

qa qs qd qf
wa ws wd wf
ea es ed ef
ra rs rd rf

with all the elements of A are new symbols, but I have to be able to retrieve the single sign symbol. I want to do various operations on A e.g., build another set of all combinations of the elements of A or test for equality.

I came up with these two solutions:

Solution 1:

(def A  {:qa [:q :a] :qs [:q :s] :qd [:q :d] :qf [:q :f]
         :wa [:w :a] :ws [:w :s] :wd [:w :d] :wf [:w :f]
         :ea [:e :a] :es [:e :s] :ed [:e :d] :ef [:e :f]
         :ra [:r :a] :rs [:r :s] :rd [:r :d] :rf [:r :f]})

(defn get-v1 [key] (first (key A)))

(defn get-v2 [key] (last (key A)))

=>(get-v1 :qa)
:q

Solution2:

(def A [:qa :qs :qd :qf
        :wa :ws :wd :wf
        :ea :es :ed :ef
        :ra :rs :rd :rf])

(defn get-v1 [key] (keyword (str (first (name key)))))

(defn get-v2 [key] (keyword (str (last (name key)))))

=>(get-v2 :ws)
:s

In fact solution 1 is incomplete, because the order of the elements of A matters too. Therefore the definition of A in solution 2 is needed. But I haven't figured out a smart way to create a sorted-map-by in solution 1.

Questions:

1. Are keywords the right way to go?

2. If so, is either one of my solutions a good way to do it or is there a much more convenient way? I tend to solution 2.

1

1 Answers

2
votes

Deriving the values from the keys is the more generic solution. This means you can give it any key and it will return the "proper" value for it. That is, you could give :xy to your second algorithm and it will try to use it even though it is not contained in A. If that's a problem, then you first solution seems better.

As for creating a sorted map for your second solution, I would probably take definition of A and generate a sorted map from it. This reduces the manual duplication while allowing you to provide the data set in a more natural way. (Plus, it's easy to test!)

(def A [:qa :qs :qd :qf
        :wa :ws :wd :wf
        :ea :es :ed :ef
        :ra :rs :rd :rf])

(defn assoc-v
  [m k]
  (let [[a b] (seq (name e))]
    (assoc m k [(keyword a) (keyword b)])))

(defn make-a
  [elements]
  (reduce assoc-v (sorted-map) elements))