在Clojure中将2元组(x,y)列表排序为集合的排序映射

在Clojure中将2元组(x,y)列表排序为集合的排序映射,clojure,Clojure,我正在尝试使用函数list of xy->sorted map of set创建sorted set的sorted map: (def in '([1 9] [1 8] [1 7] [2 1] [2 2] [2 3] [2 1] [2 2] [2 3] [2 1] [2 2] [2 3])) (def out (into (sorted-map) {1 (sorted-set 9 8 7) 2 (sorted-set 1 2 3)}))

我正在尝试使用函数
list of xy->sorted map of set
创建
sorted set
sorted map

(def in
  '([1 9] [1 8] [1 7]
     [2 1] [2 2] [2 3]
     [2 1] [2 2] [2 3]
     [2 1] [2 2] [2 3]))

(def out
  (into (sorted-map)
    {1 (sorted-set 9 8 7)
     2 (sorted-set 1 2 3)}))

(defn list-of-xy->sorted-map-of-sorted-sets [list-of-xy]
  "Take a list (or lazy-seq) of 2-tuple and return a sorted-map of sorted-sets"
  (reduce ????? list-of-xy))


; should return true
(= (list-of-xy->sorted-map-of-sorted-sets in) out)
到目前为止,我尝试通过两个步骤创建
out

(def int1
    (group-by #(first %) in))
;=> { 1 [[1 9] [1 8] [1 7]],
;     2 [[2 1] [2 2] [2 3] [2 1] [2 2] [2 3] [2 1] [2 2] [2 3]]}

(def int2
    (flatten
      (map
        #(let [[x xys] %]
           (list x (sorted-set (map last xys))))
        int1)))
;=> (1 #{7 8 9} 2 #{1 2 3}) ; <-- this is not a sorted-map (yet!)
如果通过性能测试,请告诉我:)


如果通过性能测试,请告诉我:)。

ehh@Ankur,性能测试通过!顺便说一句,我还尝试将
(映射第二个v)
更改为
(映射最后一个v)
,但您的版本更快:deeh@Ankur,性能测试通过!顺便说一句,我也尝试过将
(映射第二个v)
更改为
(映射最后一个v)
,但您的版本更快:DThanks@amalloy,我想知道,您的解决方案是否可以使用“reduced”将reduce与以下序列短路:?谢谢,如果你知道所有剩余的列表项都已经在集合中,你可以提前停止
reduced
。很难想象你怎么会知道。谢谢@amalloy,我想知道,你的解决方案是否可以使用“reduce”来短路reduce,比如:?谢谢,如果你知道所有剩余的列表项都已经在集合中,你可以提前停止
reduced
。但很难想象你怎么会知道。
(fn [a [x y]]
  (if-not (get-in a [x y])
    (update-in a [x] conj y)
    (reduced a)))
(= out (into (sorted-map)
             (map (fn [[k v]]
                    [k (apply sorted-set (map second v))])
                  (group-by first in))))
(defn list-of-xy->sorted-map-of-sorted-sets [list-of-xy]
  (let [conj (fnil conj (sorted-set))]
    (reduce (fn [acc [x y]]
              (update-in acc [x] conj y))
            (sorted-map)
            list-of-xy)))