3

我正在尝试根据日期时间值对地图进行排序。下面的代码使用来自 clj-time 的函数 -

(def items {:a {:time (date-time 2013 12)} :b {:time (date-time 2013 11)}})

(sort-by #(-> % items :month) before? items)

IllegalArgumentException 没有实现方法: :before? 协议:#'clj-time.core/DateTimeProtocol 为类找到:nil clojure.core/-cache-protocol-fn (core_deftype.clj:527)

但是我得到了上述异常。我究竟做错了什么 ?

4

3 回答 3

3

你需要这样做:

(sort-by (fn [[k v]] (-> v :time)) before? items)

如果您想要一个排序映射,那么您需要将日期时间映射作为键并将 :a :b 作为值导致排序映射对键值进行排序:

(->>  (into [] items)
      (map (fn [[k v]] [v k]))
      (flatten)
      (apply sorted-map-by #(before? (%1 :time) (%2 :time))))
于 2013-03-23T11:49:41.557 回答
3
#(-> % items :month)

相当于

#(let [res1 (items %)
       res2 (:month res1)]
   res2)

res1总是nil因为你给items它的地图条目,所以 res2nil也是。并在参数before?上抛出此异常。nil

试试这个

(def items {:a {:time (date-time 2013 10)}
            :c {:time (date-time 2013 12)}
            :b {:time (date-time 2013 11)}})

(sort-by (comp :time second) before? items)

=> ([:a {:time #<DateTime 2013-10-01T00:00:00.000Z>}]
    [:b {:time #<DateTime 2013-11-01T00:00:00.000Z>}]
    [:c {:time #<DateTime 2013-12-01T00:00:00.000Z>}])
于 2013-03-23T15:08:31.330 回答
0

你甚至不需要使用之前的?功能。sort-by 将负责按升序排序:

(def items {:a {:time (clj-time.core/date-time 2013 10)}
            :c {:time (clj-time.core/date-time 2013 11)}
            :b {:time (clj-time.core/date-time 2012 11)}})

(sort-by (comp :time second) items)

=> ([:b {:time #clj-time/date-time "2012-11-01T00:00:00.000Z"}]
    [:a {:time #clj-time/date-time "2013-10-01T00:00:00.000Z"}]
    [:c {:time #clj-time/date-time "2013-11-01T00:00:00.000Z"}])
于 2022-01-14T16:38:15.613 回答