Reputation: 18005
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
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
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
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
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