Skip to content

Commit

Permalink
added update! for dict (squashed)
Browse files Browse the repository at this point in the history
  • Loading branch information
chethega committed Jun 19, 2019
1 parent 8376535 commit dd11589
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 0 deletions.
27 changes: 27 additions & 0 deletions base/abstractdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,33 @@ function filter(f, d::AbstractDict)
return df
end

"""
update!(combine, dict::AbstractDict, key, val)
If `haskey(dict, key)`, then updates `dict[key] = combine(dict[key], val)`. Otherwise,
sets `dict[key] = combine(val)`. The new value is returned. Many concrete implementations
of `AbstractDict` can perform such updates in a single lookup.
# Examples
```jldoctest
julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
julia> update!(+, d, "a", 1)
2
julia> update!(-, d, "e", 1)
-1
julia> d
Dict{String,Int64} with 4 entries:
"c" => 3
"e" => -1
"b" => 2
"a" => 2
```
"""
update!(combine, dict::AbstractDict, key, val) = haskey(dict, key) ? dict[key] = combine(dict[key], val) : dict[val]=combine(val)

function eltype(::Type{<:AbstractDict{K,V}}) where {K,V}
if @isdefined(K)
if @isdefined(V)
Expand Down
15 changes: 15 additions & 0 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,21 @@ function setindex!(h::Dict{K,V}, v0, key::K) where V where K
return h
end

function update!(combine, h::Dict{K,V}, key, val) where {K,V}
idx = ht_keyindex2!(h, key)
if idx > 0
@inbounds h.keys[idx] = convert(K, key)
@inbounds vold = h.vals[idx]
vnew = combine(vold, val)
@inbounds h.vals[idx] = vnew
return vnew
else
vnew = combine(val)
@inbounds _setindex!(h, vnew, key, -idx)
return vnew
end
end

"""
get!(collection, key, default)
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ export
union,
unique!,
unique,
update!,
values,
valtype,
,
Expand Down
11 changes: 11 additions & 0 deletions test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ end
delete!(h, i)
end
@test isempty(h)
for i=1:2:600
update!(+, h, i, 1)
end
for j=0:3:600
update!(+, h, j, 1)
end
for i=0:600
@test (get(h, i, 0) == ((iseven(i) + rem(i, 3))==0))
end
empty!(h)

h[77] = 100
@test h[77] == 100
for i=1:10000
Expand Down

0 comments on commit dd11589

Please sign in to comment.