Mergewith() does not preserve alternate AbstractDict types. Bug?

If I have two dictionaries of some alternative type like OrderedDict

julia> using OrderedCollections
julia> a = OrderedDict("a"=>1, "b"=>"foo")
OrderedDict{String, Any} with 2 entries:
  "a" => 1
  "b" => "foo"

julia> b = OrderedDict("a"=>1, "c"=>"bar")
OrderedDict{String, Any} with 2 entries:
  "a" => 1
  "c" => "bar"

then merge() will give me a result of the same type

julia> merge(a,b)
OrderedDict{String, Any} with 3 entries:
  "a" => 1
  "b" => "foo"
  "c" => "bar"

However, if I use mergewith() the result is always a Dict

julia> mergewith(*, a, b)
Dict{String, Any} with 3 entries:
  "c" => "bar"
  "b" => "foo"
  "a" => 1

This seems inconsistent. I wanted and expected the result to be an OrderedDict. Is this a bug?

At least it’s an annoying misfeature. merge returns an OrderedDict because OrderedCollections has a specialized method. Presumably it’s missing for mergewith because nobody updated OrderedCollections after mergewith was sort of split out from merge, cf. mergewith not working properly for OrderedDict · Issue #77 · JuliaCollections/OrderedCollections.jl · GitHub.

A PR to fix this would probably be received favorably.

In the mean time a possible workaround is mergewith!(*, copy(a), b), assuming that the key and value types of a are sufficient for the merged result. Or you can skip the copy if it’s fine to mutate a.

2 Likes

PR opened Implement mergewith() for OrderedDict and LittleDict by johnomotani · Pull Request #119 · JuliaCollections/OrderedCollections.jl · GitHub.