nha
nha

Reputation: 18005

compare Clojure maps with bigdecimal and integers values

In my 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

How can I compare these maps so that the result of the last example would return true ?

Upvotes: 1

Views: 176

Answers (4)

Leon Grapenthin
Leon Grapenthin

Reputation: 9266

Compare corresponding values with ==

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

Note that both maps need to have the same keys. You might want to add a precondition like

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

Upvotes: 1

cgrand
cgrand

Reputation: 7949

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

Upvotes: 1

RedDeckWins
RedDeckWins

Reputation: 2121

Here's a solution that will work for multiple maps

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

Upvotes: 1

Diego Basch
Diego Basch

Reputation: 13059

You want to make sure that:

1) The maps have the same keys.

2) every value for a key has an equivalent (==) value in both maps.

Here's my first thought, I'm sure it could be made more succint:

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

Upvotes: 2

Related Questions