将包含可能为空的基元数组的嵌套数据结构与 clojure 进行比较。data/diff
Comparing nested data structures containing potentially empty arrays of primitives with clojure.data/diff
我正在使用 clojure。data/diff 在我的单元测试中比较嵌套数据结构。它工作得很好,直到我遇到它(IMO)在遇到空的基元数组时表现不一致的问题。
非空基元数组与包含相同类型对象(例如双精度对象)的向量相比效果很好。但是,空原始数组不等于(在 diff 函数的意义上)一个空向量甚至另一个相同类型的空数组。
这是一个显示我的问题的 repl 会话。我添加了一些评论。
nerom.nsd.dbserver=> (require '[clojure.data :as cd])
nil
;; this is as I would expect - a vector and a primitive array with
;; same contents compare equal
nerom.nsd.dbserver=> (cd/diff [[1.1 2.2]] [(double-array [1.1 2.2])])
[nil nil [[1.1 2.2]]]
;; this is inconsistent with the previous - empty double array does
;; not compare equal to an empty vector
nerom.nsd.dbserver=> (cd/diff [[]] [(double-array [])])
[[nil] [nil] nil]
;; two double arrays with the same contents compare equal
nerom.nsd.dbserver=> (cd/diff [(double-array [1.1 2.2])] [(double-array [1.1 2.2])])
[nil nil [[1.1 2.2]]]
;; except when they are empty, which is IMO inconsistent
nerom.nsd.dbserver=> (cd/diff [(double-array [])] [(double-array [])])
[[nil] [nil] nil]
如何使空数组与空向量或至少相同类型的空向量相比较?
我想我找到了线索:
如果您查看 diff
来源,您会看到以下内容:
(if (= a b)
[nil nil a]
(if (= (equality-partition a) (equality-partition b))
(diff-similar a b)
(atom-diff a b)))
首先将两个值与协议 EqualityPartition
中定义的 equality-partition
进行比较,returns 一些关键字相等性 class
因此,如果您将此协议扩展到原始数组,它们将不会被视为相等:
(require '[clojure.data :as d])
之前:
user> (d/diff [(double-array [])] [(int-array [])])
[[nil] [nil] nil]
然后扩展协议:
(extend-protocol d/EqualityPartition
(Class/forName "[D")
(equality-partition [_] :double-array))
(extend-protocol d/EqualityPartition
(Class/forName "[I")
(equality-partition [_] :int-array))
user> (d/equality-partition (double-array []))
:double-array
user> (d/equality-partition (int-array []))
:int-array
之后:
user> (d/diff [(double-array [])] [(int-array [])])
[[#object["[D" 0x1e2f0f97 "[D@1e2f0f97"]] [#object["[I" 0x207c60b5 "[I@207c60b5"]] nil]
而相似类型的数组将像以前一样进行比较
user> (d/diff [(double-array [])] [(double-array [])])
[[nil] [nil] nil]
user> (d/diff [(double-array [1])] [(double-array [10])])
[[[1.0]] [[10.0]] nil]
因此进一步朝这个方向看:您可以调整扩展此协议(以及 clojure.data
中的其他协议)的比较
我正在使用 clojure。data/diff 在我的单元测试中比较嵌套数据结构。它工作得很好,直到我遇到它(IMO)在遇到空的基元数组时表现不一致的问题。
非空基元数组与包含相同类型对象(例如双精度对象)的向量相比效果很好。但是,空原始数组不等于(在 diff 函数的意义上)一个空向量甚至另一个相同类型的空数组。
这是一个显示我的问题的 repl 会话。我添加了一些评论。
nerom.nsd.dbserver=> (require '[clojure.data :as cd])
nil
;; this is as I would expect - a vector and a primitive array with
;; same contents compare equal
nerom.nsd.dbserver=> (cd/diff [[1.1 2.2]] [(double-array [1.1 2.2])])
[nil nil [[1.1 2.2]]]
;; this is inconsistent with the previous - empty double array does
;; not compare equal to an empty vector
nerom.nsd.dbserver=> (cd/diff [[]] [(double-array [])])
[[nil] [nil] nil]
;; two double arrays with the same contents compare equal
nerom.nsd.dbserver=> (cd/diff [(double-array [1.1 2.2])] [(double-array [1.1 2.2])])
[nil nil [[1.1 2.2]]]
;; except when they are empty, which is IMO inconsistent
nerom.nsd.dbserver=> (cd/diff [(double-array [])] [(double-array [])])
[[nil] [nil] nil]
如何使空数组与空向量或至少相同类型的空向量相比较?
我想我找到了线索:
如果您查看 diff
来源,您会看到以下内容:
(if (= a b)
[nil nil a]
(if (= (equality-partition a) (equality-partition b))
(diff-similar a b)
(atom-diff a b)))
首先将两个值与协议 EqualityPartition
中定义的 equality-partition
进行比较,returns 一些关键字相等性 class
因此,如果您将此协议扩展到原始数组,它们将不会被视为相等:
(require '[clojure.data :as d])
之前:
user> (d/diff [(double-array [])] [(int-array [])])
[[nil] [nil] nil]
然后扩展协议:
(extend-protocol d/EqualityPartition
(Class/forName "[D")
(equality-partition [_] :double-array))
(extend-protocol d/EqualityPartition
(Class/forName "[I")
(equality-partition [_] :int-array))
user> (d/equality-partition (double-array []))
:double-array
user> (d/equality-partition (int-array []))
:int-array
之后:
user> (d/diff [(double-array [])] [(int-array [])])
[[#object["[D" 0x1e2f0f97 "[D@1e2f0f97"]] [#object["[I" 0x207c60b5 "[I@207c60b5"]] nil]
而相似类型的数组将像以前一样进行比较
user> (d/diff [(double-array [])] [(double-array [])])
[[nil] [nil] nil]
user> (d/diff [(double-array [1])] [(double-array [10])])
[[[1.0]] [[10.0]] nil]
因此进一步朝这个方向看:您可以调整扩展此协议(以及 clojure.data
中的其他协议)的比较