Thanks Stuart,
preserving order is a nice touch :)

I also did not realize that conj preserves sequence type ...

BTW, I hope I'm not abusing this mailing list by asking questions like
this?

Boris

On Apr 28, 5:15 pm, Stuart Sierra <the.stuart.sie...@gmail.com> wrote:
> Hi Boris, welcome to Clojure!
>
> This function looks reasonable to me.  In your example, you don't need
> to write "#(identity %)" -- just "identity" is enough.  If you want to
> preserve the order of objects in the sequence, you can use a vector
> instead of a list.
>
> I would use "contains?" in the conditional test.  It took me a while
> to realize that the values in amap will never be false/nil, so you
> don't have to worry about (amap key) being logical false.  But in
> other uses of maps, that can be a concern.
>
> So here's my version:
>
> (defn seq-to-multimap [s key-fn]
>   (reduce
>    (fn [amap item]
>      (let [key (key-fn item)]
>        (assoc amap key
>               (if (contains? amap key)
>                 (conj (amap key) item)
>                 [item]))))
>    {} s))
>
> As to whether this should return a map or a list of lists, that all
> depends on what you want to use it for.  Here's a nice demonstration:
>
> user> (seq-to-multimap (range 1 15) #(mod % 5))
> {0 [5 10], 4 [4 9 14], 3 [3 8 13], 2 [2 7 12], 1 [1 6 11]}
>
> -SS
>
> On Apr 28, 4:19 pm, Boris Mizhen <bo...@boriska.com> wrote:
>
> > Hello all,
>
> > I am starting to learn clojure. I would appreciate comments on the
> > utility function below.
> > Coding style, idiomatic Clojure, comment style, efficiency, naming
> > conventions, indentations (used slime) ... anything I should
> > improve :)
>
> > (defn seq-to-multimap [s key-fn]
> >   "takes a sequence s of possibly repeating elements
> >    and converts it to a map, where keys are obtained by applying key-
> > fn
> >    to elements of s and values are sequence of all elements of s with
> > the
> >    particular key"
> >   (reduce
> >    (fn [amap item]
> >      (let [key (key-fn item)]
> >        (assoc amap key
> >               (if-let [it (amap key)]
> >                 (conj it item)
> >                 (list item)))))
> >    {} s))
>
> > user> (seq-to-multimap [1 :key :key 2 3 3 nil] #(identity %1))
> > {nil (nil), 3 (3 3), 2 (2), :key (:key :key), 1 (1)}
>
> > Would it be better to have this function to create a list of lists
> > using an equality op instead?
>
> > Thank you!
> > Boris
--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to