views:

84

answers:

3

I have a sequence of values that I get from somewhere else, in a known order. I also have one separate value. Both of these I want to put into a struct. I.e.

(defstruct location :name :id :type :visited)

Now I have a list

(list "Name" "Id" "Type")

that is the result of a regexp.

Then I want to put a boolean in :visited; yielding a struct that looks like this:

{:name "Name" :id "Id" :type "Type" :visited true}

How do I do this? I tried various combinations of apply and struct-map. I got as far as:

(apply struct-map location (zipmap [:visited :name :id :type] (cons true (rest match))))

but that may be the wrong way to go about it altogether.

A: 

Your version looks OK. One small shortcut via into:

user> (let [match (list "Name" "Id" "Type")]
        (into {:visited true} 
              (zipmap [:name :id :type] match)))
{:visited true, :type "Type", :id "Id", :name "Name"}

merge would also have worked.

Brian Carper
+3  A: 

How about:

(def l (list "Name" "Id" "Type"))
(defstruct location :name :id :type :visited)
(assoc
   (apply struct location l)
   :visited true)
Arthur Edelstein
Yes...so easy :)
Kurt Schelfthout
+3  A: 

You should use a record not a struct if you are in 1.2.

(defrecord location [name id type visited])

(defn getLoc [[name type id] visited] (location. name id type visited))

(getLoc (list "name" "type" "id") true)
#:user.location{:name "name", :id "id", :type "type", :visited true}
nickik
+1 for the tip about the records. I don't like having to write a special function just for destructuring this particular case. Thanks!
Kurt Schelfthout
You don't have to. I just its better if you get the data as a list.
nickik