我注意到,Clojure的(1.4)似乎很乐意考虑等于载体seq
相同的载体,但同样不适用于地图:
(= [1 2] (seq [1 2]))
=> true
(= {1 2} (seq {1 2}))
=> false
的行为,为什么要=
在这种方式有什么不同?
我注意到,Clojure的(1.4)似乎很乐意考虑等于载体seq
相同的载体,但同样不适用于地图:
(= [1 2] (seq [1 2]))
=> true
(= {1 2} (seq {1 2}))
=> false
的行为,为什么要=
在这种方式有什么不同?
Clojure的=
可以被认为是分两步进行的比较:
检查的事物的类型是属于同一个“平等分区”相比,这是一个类的类型,其成员可能潜在地等于(取决于事情,比如给定的数据结构的具体成员,而不是特定类型的的分区);
如果是这样,检查是否实际被比较的东西都是平等的。
这样一个平等的分区是,“连续”的事情。 载体是考虑顺序:
(instance? clojure.lang.Sequential [])
;= true
由于有各类seqs:
(instance? clojure.lang.Sequential (seq {1 2}))
;= true
因此,如果(且仅当)及其相应的元素相等的矢量被认为等于一个起。
(请注意, (seq {})
产生nil
,这是不连续的,并比较“不等于”至()
[]
等)
在另一方面,地图构成了自己的平等分区,所以当一个哈希地图可能被认为等于有序映射,它永远不会被视为等于起。 特别是,它不等于其条目的SEQ,这是什么(seq some-map)
产生。
我想这是因为在序列顺序以及在特定位置值,其中重要的在地图键/值的顺序并不重要和语义之间的这种差异导致如图示例代码这个工作。
有关详细信息看看mapEquals
文件https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java
它检查,如果其他对象没有映射则返回false。
user=> (seq {1 2})
([1 2])
user=> (type {1 2})
clojure.lang.PersistentArrayMap
在我看来,这个例子指出,在这种情况下,他们是来自同一个类型(由派生不同类型Clojure中值的平等的观念稍有不一致seq
功能)。 它很可能是认为,这是因为它是一个派生类型进行比较来衍生它的类型和我可以理解,如果相同的逻辑应用于此相同的例如使用载体(注意在底部)是不矛盾的
内容是相同的类型:
user> (type (first (seq {1 2})))
clojure.lang.MapEntry
user> (type (first {1 2}))
clojure.lang.MapEntry
user> (= (type (first {1 2})) (type (first (seq {1 2}))))
true
user> (= (first {1 2}) (first (seq {1 2})))
true
序列具有相同的值
user> (map = (seq {1 2}) {1 2})
(true)
但它们不被认为等于用户>(= {1 2}(SEQ {1 2}))假
这是一个较长的地图也是如此:
user> (map = (seq {1 2 3 4}) {1 2 3 4})
(true true)
user> (map = (seq {1 2 3 4 5 6}) {1 2 3 4 5 6})
(true true true)
user> (map = (seq {9 10 1 2 3 4 5 6}) {9 10 1 2 3 4 5 6})
(true true true true)
即使它们不是在同一顺序 :
user> (map = (seq {9 10 1 2 3 4 5 6}) {1 2 3 4 5 6 9 10})
(true true true true)
但又不如果包含类型不同:-(
user> (= {1 2 3 4} (seq {1 2 3 4}))
false
编辑:这并不总是正确见下文:要解决这一点,你可以比较 ,这是(我相信)安全的,因为SEQ函数总是遍历整个数据结构以同样的方式和结构是不变的值之前,一切都转换为SEQ和seq
一的seq
是seq
user> (= (seq {9 10 1 2 3 4 5 6}) {1 2 3 4 5 6 9 10})
false
user> (= (seq {9 10 1 2 3 4 5 6}) (seq {1 2 3 4 5 6 9 10}))
true
user> (= [1 2 3 4] (seq [1 2 3 4]))
true
也许理解轻微不一致是可以改变的(虽然我不认为我的呼吸)学习语言或者这一天的一部分
我发现了两个产生了相同的值不同的序列,以便只在地图上的调用序列不会给你适当的地图平等地图:
user> (seq (zipmap [3 1 5 9][4 2 6 10]))
([9 10] [5 6] [1 2] [3 4])
user> (seq {9 10 5 6 1 2 3 4})
([1 2] [3 4] [5 6] [9 10])
user>
这里是我打电话给适当的地图平等的例子:
user> (def a (zipmap [3 1 5 9][4 2 6 10]))
#'user/a
user> (def b {9 10 5 6 1 2 3 4})
#'user/b
user> (every? true? (map #(= (a %) (b %)) (keys a)))
true
(seq some-hash-map)
让你条目(键/值对)的序列。
例如:
foo.core=> (seq {:a 1 :b 2 :c 3})
([:a 1] [:c 3] [:b 2])
这是不一样的[:a 1 :b 2 :c 3]