【问题标题】:compare Clojure maps with bigdecimal and integers values将 Clojure 映射与 bigdecimal 和整数值进行比较
【发布时间】:2015-08-26 16:34:21
【问题描述】:

在我的 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

我如何比较这些映射,以便最后一个示例的结果返回 true ?

【问题讨论】:

    标签: clojure hashmap bigdecimal


    【解决方案1】:

    您要确保:

    1) 地图具有相同的键。

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

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

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

    【讨论】:

    • 我喜欢这个,虽然我更喜欢 (every? #(== (m1 %) (m2 %)) k1) 而不是every?/true/for 组合。
    【解决方案2】:

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

    (defn number-equivalent [& ms]
      (->> (apply merge-with == ms)
           (every? (comp true? val))))
    

    【讨论】:

    • 如果您的目标是可变参数版本,您应该更喜欢利用 == 的可变参数实现而不是在内存中创建中间映射。
    • 这对于某些地图将无法正常工作。例如,(number-equivalent {:a true} {:b true})
    【解决方案3】:
    (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)))
    

    【讨论】:

      【解决方案4】:

      将对应的值与==比较

      (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
      

      【讨论】:

      • 仅供参考,我认为您在某处有错字。每一个?接受一个谓词,而不是一个有两个参数的函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      相关资源
      最近更新 更多