From 7556afb32edacd532758d25651dfea2a4f94655a Mon Sep 17 00:00:00 2001 From: Andrey Orst Date: Fri, 13 Nov 2020 18:57:32 +0300 Subject: fix(core): improved deep comparison --- cljlib.fnl | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'cljlib.fnl') diff --git a/cljlib.fnl b/cljlib.fnl index 07e5621..b53e04f 100644 --- a/cljlib.fnl +++ b/cljlib.fnl @@ -591,9 +591,33 @@ that would apply to that value, or `nil' if none apply and no default." ([x] true) ([x y] (if (and (= (type x) :table) (= (type y) :table)) - (and (reduce #(and $1 $2) true (mapv (fn [[k v]] (eq (. y k) v)) (kvseq x))) - (reduce #(and $1 $2) true (mapv (fn [[k v]] (eq (. x k) v)) (kvseq y)))) - (= x y))) + (let [oldmeta (getmetatable y)] + ;; In case if we'll get something like + ;; (eq {[1 2 3] {:a [1 2 3]}} {[1 2 3] {:a [1 2 3]}}) + ;; we have to do even deeper search + (setmetatable y {:__index (fn [tbl key] + (var res nil) + (each [k v (pairs tbl)] + (when (eq k key) + (set res v) + (lua :break))) + res)}) + (var [res count-a count-b] [true 0 0]) + (each [k v (pairs x)] + + + (set res (eq v (. y k))) + (set count-a (+ count-a 1)) + (when (not res) + (lua :break))) + (when res + (each [_ _ (pairs y)] + (set count-b (+ count-b 1))) + (set res (= count-a count-b))) + ;; restoring old metatable + (setmetatable y oldmeta) + res) + (= x y))) ([x y & xs] (reduce #(and $1 $2) (eq x y) (mapv #(eq x $) xs)))) -- cgit v1.2.3