将 Clojure 映射与 bigdecimal 和整数值进行比较

compare Clojure maps with bigdecimal and integers values

在我的 REPL 中:

(== 1 1M)
;;=>true
(= {:a 1 :b 2} {:a 1 :b 2})
;;=>true
(= {:a 1 :b 2} {:a 1 :b 3})
;;=>false
(= {:a 1M :b 2M} {:a 1 :b 2})
;;=>false

我如何比较这些地图以使最后一个示例的结果 return 正确?

您想确保:

1) 映射具有相同的键。

2) 键的每个值在两个映射中都有等效的 (==) 值。

这是我的第一个想法,我相信它可以更简洁:

(defn number-equivalent
  [m1 m2]
  (let [k1 (keys m1)]
    (and (= k1 (keys m2))
          (every? true?
                  (for [k k1]
                    (== (m1 k)
                        (m2 k)))))))

将对应值与==

进行比较
(defn compare-nums
  [m1 m2]
  (every? (fn [[k v]] (== (get m1 k) v)) m2))

请注意,两个地图需要具有相同的键。您可能想添加一个先决条件,例如

  {:pre [(= (.keySet m1) (.keySet m2))]} ; ensure both maps have the same keys

这是一个适用于多个地图的解决方案

(defn number-equivalent [& ms]
  (->> (apply merge-with == ms)
       (every? (comp true? val))))
(defn map== [a b]
  (and (= (count a) (count b))
    (reduce-kv (fn [_ k va]
                 (or (and (number? va)
                       (let [vb (get b k)]
                         (and (number? vb)
                           (== va vb))))
                   (reduced false)))
      true a)))