Skip to content

Commit

Permalink
Added implementation of get(coll, key) -> Nullable.
Browse files Browse the repository at this point in the history
This returns a Nullable value corresponding to the key (or null).
Includes specialization for various dictionary types.
Fixes JuliaLang#13055
  • Loading branch information
dbeach24 committed Aug 30, 2016
1 parent 7199111 commit b8c1e81
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 0 deletions.
5 changes: 5 additions & 0 deletions base/collections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ function get{K,V}(pq::PriorityQueue{K,V}, key, deflt)
i == 0 ? deflt : pq.xs[i].second
end

function get{K,V}(pq::PriorityQueue{K,V}, key)
i = get(pq.index, key, 0)
i == 0 ? Nullable{V}() : Nullable{V}(pq.xs[i].second)
end


# Change the priority of an existing element, or equeue it if it isn't present.
function setindex!{K,V}(pq::PriorityQueue{K, V}, value, key)
Expand Down
16 changes: 16 additions & 0 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const secret_table_token = :__c782dbf1cf4d6a2e5e3865d7e95634f2e09b5902__

haskey(d::Associative, k) = in(k,keys(d))

get{K,V}(d::Associative{K,V}, k) = haskey(d, k) ? Nullable{V}(d[k]::V) : Nullable{V}()

function in(p::Pair, a::Associative, valcmp=(==))
v = get(a,p[1],secret_table_token)
if !is(v, secret_table_token)
Expand Down Expand Up @@ -698,6 +700,11 @@ function get{K,V}(default::Callable, h::Dict{K,V}, key)
return (index < 0) ? default() : h.vals[index]::V
end

function get{K,V}(h::Dict{K,V}, key)
index = ht_keyindex(h, key)
return (index<0) ? Nullable{V}() : Nullable{V}(h.vals[index]::V)
end

haskey(h::Dict, key) = (ht_keyindex(h, key) >= 0)
in{T<:Dict}(key, v::KeyIterator{T}) = (ht_keyindex(v.dict, key) >= 0)

Expand Down Expand Up @@ -828,6 +835,7 @@ function getindex(dict::ImmutableDict, key)
end
throw(KeyError(key))
end

function get(dict::ImmutableDict, key, default)
while isdefined(dict, :parent)
dict.key == key && return dict.value
Expand All @@ -836,6 +844,14 @@ function get(dict::ImmutableDict, key, default)
return default
end

function get{K,V}(dict::ImmutableDict{K,V}, key)
while isdefined(dict, :parent)
dict.key == key && return Nullable{V}(dict.value::V)
dict = dict.parent
end
Nullable{V}()
end

# this actually defines reverse iteration (e.g. it should not be used for merge/copy/filter type operations)
start(t::ImmutableDict) = t
next{K,V}(::ImmutableDict{K,V}, t) = (Pair{K,V}(t.key, t.value), t.parent)
Expand Down
8 changes: 8 additions & 0 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4014,6 +4014,14 @@ end
"""
get

"""
get(collection, key) -> Nullable
Return the value stored for the given key as `Nullable(value)`,
or if no mapping for the key is present, return null.
"""
get(collection, key)

"""
.!=(x, y)
.≠(x,y)
Expand Down
1 change: 1 addition & 0 deletions base/weakkeydict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ end

get{K}(wkh::WeakKeyDict{K}, key, default) = lock(() -> get(wkh.ht, key, default), wkh)
get{K}(default::Callable, wkh::WeakKeyDict{K}, key) = lock(() -> get(default, wkh.ht, key), wkh)
get{K}(wkh::WeakKeyDict{K}, key) = lock(() -> get(wkh.ht, key), wkh)
get!{K}(wkh::WeakKeyDict{K}, key, default) = lock(() -> get!(wkh.ht, key, default), wkh)
get!{K}(default::Callable, wkh::WeakKeyDict{K}, key) = lock(() -> get!(default, wkh.ht, key), wkh)
pop!{K}(wkh::WeakKeyDict{K}, key) = lock(() -> pop!(wkh.ht, key), wkh)
Expand Down
6 changes: 6 additions & 0 deletions doc/stdlib/collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,12 @@ Given a dictionary ``D``, the syntax ``D[x]`` returns the value of key ``x`` (if
Determine whether a collection has a mapping for a given key.

.. function:: get(collection, key) -> Nullable

.. Docstring generated from Julia source
Return the value stored for the given key as ``Nullable(value)``\ , or if no mapping for the key is present, return null.

.. function:: get(collection, key, default)

.. Docstring generated from Julia source
Expand Down
8 changes: 8 additions & 0 deletions test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ let f(x) = x^2, d = Dict(8=>19)
f(4)
end == 16

# get (returning Nullable)
@test get(get(d, 8)) == 19
@test isnull(get(d, 13))

@test d == Dict(8=>19, 19=>2, 42=>4)
end

Expand Down Expand Up @@ -448,6 +452,10 @@ let d = ImmutableDict{String, String}(),
@test in(k2 => 1.0, dnum, is)
@test !in(k2 => 1, dnum, <)
@test in(k2 => 0, dnum, <)
@test get(d1, "key1") === Nullable{String}(v1)
@test get(d4, "key1") === Nullable{String}(v2)
@test get(d4, "foo") === Nullable{String}()
@test get(d, k1) === Nullable{String}()
@test get(d1, "key1", :default) === v1
@test get(d4, "key1", :default) === v2
@test get(d4, "foo", :default) === :default
Expand Down
18 changes: 18 additions & 0 deletions test/priorityqueue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,21 @@ for priority in values(priorities)
heappush!(xs, priority)
end
@test issorted([heappop!(xs) for _ in length(priorities)])


# test length, in, haskey, get
let
pq = PriorityQueue(Dict(
i => i+5 for i in 1:5
))
@test length(pq) == 5

for i in 1:5
@test haskey(pq, i)
@test (i=>1+5) in pq
@test get(pq, i, 0) == i + 5
@test get(get(pq, i)) == i+5
end
@test get(pq, 10, 0) == 0
@test isnull(get(pq, 10))
end

0 comments on commit b8c1e81

Please sign in to comment.