Skip to content

Commit ee7325a

Browse files
committed
Added implementation of tryget(coll, key) for Associative.
This returns a Nullable value corresponding to the key (or null). Includes specialization for dictionaries. Fixes #13055
1 parent 7199111 commit ee7325a

File tree

5 files changed

+38
-0
lines changed

5 files changed

+38
-0
lines changed

base/dict.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ const secret_table_token = :__c782dbf1cf4d6a2e5e3865d7e95634f2e09b5902__
66

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

9+
"""
10+
tryget(collection, key)
11+
12+
Return the value stored for the given key as `Nullable(value)`,
13+
or if no mapping for the key is present, return null.
14+
"""
15+
tryget{K,V}(d::Associative{K,V}, k) = haskey(d, k) ? Nullable{V}(d[k]::V) : Nullable{V}()
16+
917
function in(p::Pair, a::Associative, valcmp=(==))
1018
v = get(a,p[1],secret_table_token)
1119
if !is(v, secret_table_token)
@@ -698,6 +706,11 @@ function get{K,V}(default::Callable, h::Dict{K,V}, key)
698706
return (index < 0) ? default() : h.vals[index]::V
699707
end
700708

709+
function tryget{K,V}(h::Dict{K,V}, key)
710+
index = ht_keyindex(h, key)
711+
return (index<0) ? Nullable{V}() : Nullable{V}(h.vals[index]::V)
712+
end
713+
701714
haskey(h::Dict, key) = (ht_keyindex(h, key) >= 0)
702715
in{T<:Dict}(key, v::KeyIterator{T}) = (ht_keyindex(v.dict, key) >= 0)
703716

@@ -828,6 +841,7 @@ function getindex(dict::ImmutableDict, key)
828841
end
829842
throw(KeyError(key))
830843
end
844+
831845
function get(dict::ImmutableDict, key, default)
832846
while isdefined(dict, :parent)
833847
dict.key == key && return dict.value
@@ -836,6 +850,14 @@ function get(dict::ImmutableDict, key, default)
836850
return default
837851
end
838852

853+
function tryget{K,V}(dict::ImmutableDict{K,V}, key)
854+
while isdefined(dict, :parent)
855+
dict.key == key && return Nullable{V}(dict.value::V)
856+
dict = dict.parent
857+
end
858+
Nullable{V}()
859+
end
860+
839861
# this actually defines reverse iteration (e.g. it should not be used for merge/copy/filter type operations)
840862
start(t::ImmutableDict) = t
841863
next{K,V}(::ImmutableDict{K,V}, t) = (Pair{K,V}(t.key, t.value), t.parent)

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ export
777777
splice!,
778778
symdiff!,
779779
symdiff,
780+
tryget,
780781
union!,
781782
union,
782783
unique,

base/weakkeydict.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ get{K}(wkh::WeakKeyDict{K}, key, default) = lock(() -> get(wkh.ht, key, default)
4242
get{K}(default::Callable, wkh::WeakKeyDict{K}, key) = lock(() -> get(default, wkh.ht, key), wkh)
4343
get!{K}(wkh::WeakKeyDict{K}, key, default) = lock(() -> get!(wkh.ht, key, default), wkh)
4444
get!{K}(default::Callable, wkh::WeakKeyDict{K}, key) = lock(() -> get!(default, wkh.ht, key), wkh)
45+
tryget{K}(wkh::WeakKeyDict{K}, key) = lock(() -> tryget(wkh.ht, key), wkh)
4546
pop!{K}(wkh::WeakKeyDict{K}, key) = lock(() -> pop!(wkh.ht, key), wkh)
4647
pop!{K}(wkh::WeakKeyDict{K}, key, default) = lock(() -> pop!(wkh.ht, key, default), wkh)
4748
delete!{K}(wkh::WeakKeyDict{K}, key) = lock(() -> delete!(wkh.ht, key), wkh)

doc/stdlib/collections.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,12 @@ Given a dictionary ``D``, the syntax ``D[x]`` returns the value of key ``x`` (if
10081008
time()
10091009
end
10101010
1011+
.. function:: tryget(collection, key)
1012+
1013+
.. Docstring generated from Julia source
1014+
1015+
Return the value stored for the given key as ``Nullable(value)``\ , or if no mapping for the key is present, return null.
1016+
10111017
.. function:: get!(collection, key, default)
10121018

10131019
.. Docstring generated from Julia source

test/dict.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ let f(x) = x^2, d = Dict(8=>19)
256256
f(4)
257257
end == 16
258258

259+
# tryget (returns Nullable)
260+
@test get(tryget(d, 8)) == 19
261+
@test isnull(tryget(d, 13))
262+
259263
@test d == Dict(8=>19, 19=>2, 42=>4)
260264
end
261265

@@ -452,6 +456,10 @@ let d = ImmutableDict{String, String}(),
452456
@test get(d4, "key1", :default) === v2
453457
@test get(d4, "foo", :default) === :default
454458
@test get(d, k1, :default) === :default
459+
@test tryget(d1, "key1") === Nullable{String}(v1)
460+
@test tryget(d4, "key1") === Nullable{String}(v2)
461+
@test tryget(d4, "foo") === Nullable{String}()
462+
@test tryget(d, k1) === Nullable{String}()
455463
@test d1["key1"] === v1
456464
@test d4["key1"] === v2
457465
@test similar(d3) === d

0 commit comments

Comments
 (0)