我正在尝试使用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回答接受了。到目前为止,它是更快的解决方案。对于我的实际问题,来自@amalloy解决方案(+1)的(update-in acc [x] conj y)
通过reduced
打开了通往get-in
的路。我正在使用的还原功能是:
(fn [a [x y]]
(if-not (get-in a [x y])
(update-in a [x] conj y)
(reduced a)))
答案 0 :(得分:2)
(= out (into (sorted-map)
(map (fn [[k v]]
[k (apply sorted-set (map second v))])
(group-by first in))))
如果这通过了您的性能测试,请告诉我:)。
答案 1 :(得分: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)))