Skip to content

Commit

Permalink
Merge pull request JuliaLang#14937 from stevengj/dictfilter
Browse files Browse the repository at this point in the history
improved Dict filtering
  • Loading branch information
stevengj committed Feb 4, 2016
2 parents c200b4c + 5497cb7 commit baf336f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
31 changes: 27 additions & 4 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,27 @@ function merge(d::Associative, others::Associative...)
end

function filter!(f, d::Associative)
badkeys = Array(keytype(d), 0)
for (k,v) in d
if !f(k,v)
delete!(d,k)
end
# don't delete!(d, k) here, since associative types
# may not support mutation during iteration
f(k,v) || push!(badkeys, k)
end
for k in badkeys
delete!(d, k)
end
return d
end
filter(f, d::Associative) = filter!(f,copy(d))
function filter(f, d::Associative)
# don't just do filter!(f, copy(d)): avoid making a whole copy of d
df = similar(d)
for (k,v) in d
if f(k,v)
df[k] = v
end
end
return df
end

eltype{K,V}(::Type{Associative{K,V}}) = Pair{K,V}

Expand Down Expand Up @@ -866,6 +879,16 @@ function next{K,V}(t::WeakKeyDict{K,V}, i)
end
length(t::WeakKeyDict) = length(t.ht)

# For these Associative types, it is safe to implement filter!
# by deleting keys during iteration.
function filter!(f, d::Union{ObjectIdDict,Dict,WeakKeyDict})
for (k,v) in d
if !f(k,v)
delete!(d,k)
end
end
return d
end

immutable ImmutableDict{K, V} <: Associative{K,V}
parent::ImmutableDict{K, V}
Expand Down
7 changes: 7 additions & 0 deletions test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,10 @@ let d = ImmutableDict{UTF8String, UTF8String}(),
@test_throws KeyError d[k1]
@test_throws KeyError d1["key2"]
end

# filtering
let d = Dict(zip(1:1000,1:1000)), f = (k,v) -> iseven(k)
@test filter(f, d) == filter!(f, copy(d)) ==
invoke(filter!, (Function, Associative), f, copy(d)) ==
Dict(zip(2:2:1000, 2:2:1000))
end

0 comments on commit baf336f

Please sign in to comment.