diff --git a/base/dict.jl b/base/dict.jl index 045fb8b23d0e8..3f0f5eab507b7 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -554,6 +554,11 @@ function get{K,V}(h::Dict{K,V}, key, deflt) return (index<0) ? deflt : h.vals[index]::V end +function get{K,V}(deflt::Function, h::Dict{K,V}, key) + index = ht_keyindex(h, key) + return (index<0) ? deflt() : 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) @@ -665,6 +670,9 @@ function getkey{K}(wkh::WeakKeyDict{K}, kk, deflt) end get{K}(wkh::WeakKeyDict{K}, key, def) = get(wkh.ht, key, def) +get{K}(def::Function, wkh::WeakKeyDict{K}, key) = get(def, wkh.ht, key) +get!{K}(wkh::WeakKeyDict{K}, key, def) = get!(wkh.ht, key, def) +get!{K}(def::Function, wkh::WeakKeyDict{K}, key) = get!(def, wkh.ht, key) pop!{K}(wkh::WeakKeyDict{K}, key) = pop!(wkh.ht, key) pop!{K}(wkh::WeakKeyDict{K}, key, def) = pop!(wkh.ht, key, def) delete!{K}(wkh::WeakKeyDict{K}, key) = delete!(wkh.ht, key) diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index 3ed6541a49754..02af58c01f1c2 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -727,6 +727,17 @@ Given a dictionary ``D``, the syntax ``D[x]`` returns the value of key ``x`` (if Return the value stored for the given key, or the given default value if no mapping for the key is present. +.. function:: get(f::Function, collection, key) + + Return the value stored for the given key, or if no mapping for the key is present, return ``f()``. Use ``get!`` to also store the default value in the dictionary. + + This is intended to be called using ``do`` block syntax:: + + get(dict, key) do + # default value calculated here + time() + end + .. function:: get!(collection, key, default) Return the value stored for the given key, or if no mapping for the key is present, store ``key => default``, and return ``default``. diff --git a/test/collections.jl b/test/collections.jl index f7f1872d5f4bc..e60d759ab6243 100644 --- a/test/collections.jl +++ b/test/collections.jl @@ -150,14 +150,25 @@ d4[1001] = randstring(3) # get! (get with default values assigned to the given location) let + f(x) = x^2 d = {8=>19} def = {} @test get!(d, 8, 5) == 19 @test get!(d, 19, 2) == 2 - @test get!(d, 42) do - int(e^2) - end == 7 - @test d == {8=>19, 19=>2, 42=>7} + + @test get!(d, 42) do # d is updated with f(2) + f(2) + end == 4 + + @test get!(d, 42) do # d is not updated + f(200) + end == 4 + + @test get(d, 13) do # d is not updated + f(4) + end == 16 + + @test d == {8=>19, 19=>2, 42=>4} end # issue #2540