Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add methods to reduce, specialized for merge on Dict #26440

Merged
merged 4 commits into from
Apr 4, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,12 @@ end

filter!(f, d::Dict) = filter_in_one_pass!(f, d)

function reduce(::typeof(merge), items::Vector{<:Dict})
Copy link
Member

@rfourquet rfourquet Apr 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to allow AbstractVector{<:Dict} ?
(sorry for a last minute comment!)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC it triggered ambiguities (that's probably buried in a comment above). It would be useful to try to generalize, but for now I'd say it's already an improvement.

K = mapreduce(keytype, promote_type, items)
V = mapreduce(valtype, promote_type, items)
return reduce(merge!, items; init=Dict{K,V}())
end

struct ImmutableDict{K,V} <: AbstractDict{K,V}
parent::ImmutableDict{K,V}
key::K
Expand Down
17 changes: 17 additions & 0 deletions test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,23 @@ end
@test d1 == Dict("A" => 1, "B" => 15, "C" => 28)
end

@testset "Dict reduce merge" begin
function f(i::Vector{<:Dict}, o)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be check_merge ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh, I knew editing online was risky...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree check_merge is better. I modeled the name f on a similar function in the file.

r1 = reduce(merge, i)
r2 = merge(i...)
t = typeof(o)
@test r1 == o
@test r2 == o
@test typeof(r1) == t
@test typeof(r2) == t
end
check_merge([Dict(1=>2), Dict(1.0=>2.0)], Dict(1.0=>2.0))
check_merge([Dict(1=>2), Dict(2=>Complex(1.0, 1.0))],
Dict(2=>Complex(1.0, 1.0), 1=>Complex(2.0, 0.0)))
check_merge([Dict(1=>2), Dict(3=>4)], Dict(3=>4, 1=>2))
check_merge([Dict(3=>4), Dict(:a=>5)], Dict(:a => 5, 3 => 4))
end

@testset "misc error/io" begin
d = Dict('a'=>1, 'b'=>1, 'c'=> 3)
@test_throws ErrorException 'a' in d
Expand Down