(oops my earlier message isn't quite right, here's the correct one)

You also need to clarify your intention: are you adding an author to a list of authors, or setting the single author?
I suppose the first, but then you need to be clear on what the list of authors is.
In idiomatic clojure you'll want it to be a vector of authors, so if an author is a map like {:name "Gerald J. Sussman"}, then :authors must be associated to a vector of maps.
Also bear in mind that assoc is geared towards associative data structures such as maps, while conj is geared towards sequential data structures such as vectors.
That being said, you can still use assoc on vectors (indices are the keys) and use conj on maps (with a vector in the form of [key value]), but that's polymorphism convenience, not idiomatic.
In the end add to a new author, you need to do:
(assoc book :authors (conj (get book :authors) new-author))
Which can also be made more idiomatic as already mentioned:
(update-in book [:authors] assoc new-author)
The twisted way of doing it would be:
(conj book [:authors (conj (:authors book) new-author)])

Try this in a REPL:
(def book {:title "zbook" :authors [{:name "James"}]})
(def new-author {:name "Joe"})
(assoc book :authors (conj (get book :authors) new-author))
(update-in book [:authors] conj new-author)
(conj book [:authors (conj (:authors book) new-author)])



On 29/10/14 12:20, Roelof Wobben wrote:
Thanks James,

But how do I use assoc with it

I tried this :

(defn add-author [book new-author]
  (assoc book (conj (book :authors) new-author)))

but then I see this message :

ArityException Wrong number of args (2) passed to: core$assoc  clojure.lang.AFn.throwArity (AFn.java:437)         

Roelof


Op woensdag 29 oktober 2014 12:08:35 UTC+1 schreef James Reeves:
On 29 October 2014 11:01, Roelof Wobben <rwo...@hotmail.com> wrote:
For a exercise I have to add something to the end of a existing map.

So I thought this would work :

(defn add-author [book new-author]
  (assoc book (conj :authors new-author)))

Take a look at that conj _expression_ on its own:

    (conj :authors new-author)

You're trying to conjoin "new-author" onto the keyword :authors, but keywords aren't collections. That's what the error means. It's saying that it expected a collection, but you've supplied a keyword instead.

What you want is:

    (conj (get book :authors) new-author)

Which can also be written:

    (conj (book :authors) new-author)

    (conj (:authors book) new-author)

These two expressions are shortcuts for the above "get" function. They work because maps and keywords can act as functions.

- James
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to