0

我正在尝试sorted-map使用sorted-set以下功能创建一个list-of-xy->sorted-map-of-sets

(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!)

in --> out将性能作为优先事项进行转型的更好方法是什么?


顺便提一句

@Ankur 回答被接受。这是迄今为止更快的解决方案。

对于我的实际问题,(update-in acc [x] conj y)@amalloy 解决方案 (+1) 开辟了通往reducedvia的道路get-in。我正在使用的减少功能是:

(fn [a [x y]]
  (if-not (get-in a [x y])
    (update-in a [x] conj y)
    (reduced a)))
4

2 回答 2

2
(= out (into (sorted-map)
             (map (fn [[k v]]
                    [k (apply sorted-set (map second v))])
                  (group-by first in))))

让我知道这是否通过了您的性能测试:)。

于 2013-04-16T09:44:44.757 回答
1
(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)))
于 2013-04-16T22:57:50.350 回答