我正在使用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]
如何使空数组比较空矢量或至少是相同类型的空矢量?
答案 0 :(得分:2)
我想我找到了一个线索:
如果你看一下diff
来源,你会看到以下内容:
(if (= a b)
[nil nil a]
(if (= (equality-partition a) (equality-partition b))
(diff-similar a b)
(atom-diff a b)))
首先将两个值与equality-partition
进行比较,EqualityPartition
在协议(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
进一步朝这个方向看:你可以调整扩展这个协议的比较(以及public static void main(String[] args) {
String testValue="5006,3030,8080-8083";
Integer[]result=parseElements(testValue);
for (Integer i:result){
System.out.println(i);
}
}
/**
* NumberList is a string of comma-separated elements that are either integers, or a range of integers of the form a-b.
* @param numberList
* @return all the integers in the list, and in ranges in the list, in a sorted list
*/
private static Integer[] parseElements(String integerList) {
ArrayList<Integer> integers=new ArrayList<Integer>();
String[] csvs=integerList.split(",");
for(String csv : csvs){
if(csv.contains("-")){
String[] range=csv.split("-");
Integer left=Integer.decode(range[0]);
Integer right=Integer.decode(range[1]);
for(Integer i=left;i<=right;i++){
integers.add(i);
}
} else {
integers.add(Integer.decode(csv));
}
}
Collections.sort(integers);
return integers.toArray(new Integer[0]);
}
的其他协议)