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 -~----------~----~----~----~------~----~------~--~---