Skip to content

Commit b8c1e81

Browse files
committed
Added implementation of get(coll, key) -> Nullable.
This returns a Nullable value corresponding to the key (or null). Includes specialization for various dictionary types. Fixes #13055
1 parent 7199111 commit b8c1e81

File tree

7 files changed

+62
-0
lines changed

7 files changed

+62
-0
lines changed

base/collections.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ function get{K,V}(pq::PriorityQueue{K,V}, key, deflt)
323323
i == 0 ? deflt : pq.xs[i].second
324324
end
325325

326+
function get{K,V}(pq::PriorityQueue{K,V}, key)
327+
i = get(pq.index, key, 0)
328+
i == 0 ? Nullable{V}() : Nullable{V}(pq.xs[i].second)
329+
end
330+
326331

327332
# Change the priority of an existing element, or equeue it if it isn't present.
328333
function setindex!{K,V}(pq::PriorityQueue{K, V}, value, key)

base/dict.jl

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

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

9+
get{K,V}(d::Associative{K,V}, k) = haskey(d, k) ? Nullable{V}(d[k]::V) : Nullable{V}()
10+
911
function in(p::Pair, a::Associative, valcmp=(==))
1012
v = get(a,p[1],secret_table_token)
1113
if !is(v, secret_table_token)
@@ -698,6 +700,11 @@ function get{K,V}(default::Callable, h::Dict{K,V}, key)
698700
return (index < 0) ? default() : h.vals[index]::V
699701
end
700702

703+
function get{K,V}(h::Dict{K,V}, key)
704+
index = ht_keyindex(h, key)
705+
return (index<0) ? Nullable{V}() : Nullable{V}(h.vals[index]::V)
706+
end
707+
701708
haskey(h::Dict, key) = (ht_keyindex(h, key) >= 0)
702709
in{T<:Dict}(key, v::KeyIterator{T}) = (ht_keyindex(v.dict, key) >= 0)
703710

@@ -828,6 +835,7 @@ function getindex(dict::ImmutableDict, key)
828835
end
829836
throw(KeyError(key))
830837
end
838+
831839
function get(dict::ImmutableDict, key, default)
832840
while isdefined(dict, :parent)
833841
dict.key == key && return dict.value
@@ -836,6 +844,14 @@ function get(dict::ImmutableDict, key, default)
836844
return default
837845
end
838846

847+
function get{K,V}(dict::ImmutableDict{K,V}, key)
848+
while isdefined(dict, :parent)
849+
dict.key == key && return Nullable{V}(dict.value::V)
850+
dict = dict.parent
851+
end
852+
Nullable{V}()
853+
end
854+
839855
# this actually defines reverse iteration (e.g. it should not be used for merge/copy/filter type operations)
840856
start(t::ImmutableDict) = t
841857
next{K,V}(::ImmutableDict{K,V}, t) = (Pair{K,V}(t.key, t.value), t.parent)

base/docs/helpdb/Base.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4014,6 +4014,14 @@ end
40144014
"""
40154015
get
40164016

4017+
"""
4018+
get(collection, key) -> Nullable
4019+
4020+
Return the value stored for the given key as `Nullable(value)`,
4021+
or if no mapping for the key is present, return null.
4022+
"""
4023+
get(collection, key)
4024+
40174025
"""
40184026
.!=(x, y)
40194027
.≠(x,y)

base/weakkeydict.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ end
4040

4141
get{K}(wkh::WeakKeyDict{K}, key, default) = lock(() -> get(wkh.ht, key, default), wkh)
4242
get{K}(default::Callable, wkh::WeakKeyDict{K}, key) = lock(() -> get(default, wkh.ht, key), wkh)
43+
get{K}(wkh::WeakKeyDict{K}, key) = lock(() -> get(wkh.ht, key), wkh)
4344
get!{K}(wkh::WeakKeyDict{K}, key, default) = lock(() -> get!(wkh.ht, key, default), wkh)
4445
get!{K}(default::Callable, wkh::WeakKeyDict{K}, key) = lock(() -> get!(default, wkh.ht, key), wkh)
4546
pop!{K}(wkh::WeakKeyDict{K}, key) = lock(() -> pop!(wkh.ht, key), wkh)

doc/stdlib/collections.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,12 @@ Given a dictionary ``D``, the syntax ``D[x]`` returns the value of key ``x`` (if
987987
988988
Determine whether a collection has a mapping for a given key.
989989

990+
.. function:: get(collection, key) -> Nullable
991+
992+
.. Docstring generated from Julia source
993+
994+
Return the value stored for the given key as ``Nullable(value)``\ , or if no mapping for the key is present, return null.
995+
990996
.. function:: get(collection, key, default)
991997

992998
.. 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+
# get (returning Nullable)
260+
@test get(get(d, 8)) == 19
261+
@test isnull(get(d, 13))
262+
259263
@test d == Dict(8=>19, 19=>2, 42=>4)
260264
end
261265

@@ -448,6 +452,10 @@ let d = ImmutableDict{String, String}(),
448452
@test in(k2 => 1.0, dnum, is)
449453
@test !in(k2 => 1, dnum, <)
450454
@test in(k2 => 0, dnum, <)
455+
@test get(d1, "key1") === Nullable{String}(v1)
456+
@test get(d4, "key1") === Nullable{String}(v2)
457+
@test get(d4, "foo") === Nullable{String}()
458+
@test get(d, k1) === Nullable{String}()
451459
@test get(d1, "key1", :default) === v1
452460
@test get(d4, "key1", :default) === v2
453461
@test get(d4, "foo", :default) === :default

test/priorityqueue.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,21 @@ for priority in values(priorities)
107107
heappush!(xs, priority)
108108
end
109109
@test issorted([heappop!(xs) for _ in length(priorities)])
110+
111+
112+
# test length, in, haskey, get
113+
let
114+
pq = PriorityQueue(Dict(
115+
i => i+5 for i in 1:5
116+
))
117+
@test length(pq) == 5
118+
119+
for i in 1:5
120+
@test haskey(pq, i)
121+
@test (i=>1+5) in pq
122+
@test get(pq, i, 0) == i + 5
123+
@test get(get(pq, i)) == i+5
124+
end
125+
@test get(pq, 10, 0) == 0
126+
@test isnull(get(pq, 10))
127+
end

0 commit comments

Comments
 (0)