OrderedCollections.jl
OrderedCollections.jl copied to clipboard
Equality of OrderedDict
I am a little confused by the following, is it intentional that ==
does not take into account the order of keys for OrderedDict
?
julia> a1 = OrderedDict(:A => 1, :B => 2, :C => 3)
OrderedDict{Symbol, Int64} with 3 entries:
:A => 1
:B => 2
:C => 3
julia> a2 = OrderedDict(:B => 2, :A => 1, :C => 3)
OrderedDict{Symbol, Int64} with 3 entries:
:B => 2
:A => 1
:C => 3
julia> a1 == a2
true
this is mainly motivated by testing purposes, as I think in tests one wants to check that also the keys order is correct. Well, arguably one can always do
@test all(kv1 == kv2 for (kv1, kv2) in zip(a1, a2))
so maybe it's not a biggie.
This is because it is falling back to the generic ==
on AbstractDict
s, which are unordered.
julia> od = OrderedDict(1=>2)
OrderedDict{Int64, Int64} with 1 entry:
1 => 2
julia> @which ==(od, od)
==(l::AbstractDict, r::AbstractDict) in Base at abstractdict.jl:468
Whether or not this is sensible is not clear to me.
For what it is worth our behavour disagrees with python.
>>> from collections import OrderedDict
>>> d = OrderedDict.fromkeys('abcde')
>>> d2 = OrderedDict.fromkeys('edcba')
>>> d==d2
False
>>> d==d
True
Python treats ordered dicts as equal only if they have the same contents in the same order)
I definitely expected that ==
would differentiate between two OrderedDicts if they differ in order. Isn´t that the whole point, i.e. saying that "no these are not same despite having the same elements, because they are in different order".
For any type T
, x::T
and y::T
should not have x == y
unless x
and y
agree on all aspects of their public API. Since order is part of the public API of Ordered
containers, they should not be ==(::T, ::T)
unless they agree on order.