In Clojure, how to group elements?

Meditating on @mike t's answer, I've come up with:

(defn agg[x y] (if (coll? x) (cons y x) (list y x)))
(apply merge-with agg (map (partial apply hash-map) data))

This solution works also when the keys appear more than twice on data:

 (apply merge-with agg (map (partial apply hash-map) 
     [[:morning :pear][:morning :mango][:evening :mango] [:evening :pear] [:evening :kiwi]]))
;{:morning (:mango :pear), :evening (:kiwi :pear :mango)}

Don't be too quick to dismiss group-by, it has aggregated your data by the desired key and it hasn't changed the data. Any other function expecting a sequence of moment-fruit pairs will accept any value looked up in the map returned by group-by.

In terms of computing the summary my inclination was to reach for merge-with but for that I had to transform the input data into a sequence of maps and construct a "base-map" with the required keys and empty-vectors as values.

(let [i-maps (for [[moment fruit] data] {moment fruit})
      base-map (into {} 
                  (for [key (into #{} (map first data))] 
                    [key []]))]
      (apply merge-with conj base-map i-maps))

{:morning [:pear :mango], :evening [:mango :pear]}

I've come across similar grouping problems. Usually I end up plugging merge-with or update-in into some seq processing step:

(apply merge-with list (map (partial apply hash-map) data))

You get a map, but this is just a seq of key-value pairs:

user> (apply merge-with list (map (partial apply hash-map) data))
{:morning (:pear :mango), :evening (:mango :pear)}
user> (seq *1)
([:morning (:pear :mango)] [:evening (:mango :pear)])

This solution only gets what you want if each key appears twice, however. This might be better:

(reduce (fn [map [x y]] (update-in map [x] #(cons y %))) {} data)

Both of these feel "more functional" but also feel a little convoluted. Don't be too quick to dismiss your solution, it's easy-to-understand and functional enough.