1414# subclassed.
1515#
1616
17+ """
18+ DefaultDictBase{K,V,F,D}(default[, dict][, pairs...]; passkey=false)
19+
20+ Internal base type for DefaultDict and DefaultOrderedDict.
21+
22+ This type handles the core "default on miss" behavior, where accessing
23+ a missing key returns (and stores) a default value.
24+
25+ # Parameters
26+
27+ - `K` Key type
28+ - `V` Value type
29+ - `F` Type of the default value or callable
30+ - `D` Type of the underlying dictionary
31+ - `default` Default value or callable to use for missing keys
32+ - `passkey::Bool=false` If true and default is callable, pass the key to the default function
33+
34+ """
1735struct DefaultDictBase{K,V,F,D} <: AbstractDict{K,V}
1836 default:: F
1937 d:: D
@@ -58,8 +76,21 @@ DefaultDictBase{K,V}(default::F; kwargs...) where {K,V,F} = DefaultDictBase{K,V,
5876# calls setindex!
5977@delegate_return_parent DefaultDictBase. d [ Base. delete!, Base. empty!, Base. setindex!, Base. sizehint! ]
6078
79+ """
80+ empty(d::DefaultDictBase)
81+
82+ Create an empty DefaultDictBase with the same default and passkey settings.
83+ """
6184Base. empty (d:: DefaultDictBase{K,V,F} ) where {K,V,F} = DefaultDictBase {K,V,F} (d. default; passkey= d. passkey)
6285
86+ """
87+ getindex(d::DefaultDictBase, key)
88+
89+ Return the value for `key` if it exists, otherwise return and store the default value.
90+
91+ For non-callable defaults, returns the constant value.
92+ For callable defaults, calls the function and stores the result.
93+ """
6394Base. getindex (d:: DefaultDictBase , key) = get! (d. d, key, d. default)
6495
6596function Base. getindex (d:: DefaultDictBase{K,V,F} , key) where {K,V,F<: Base.Callable }
@@ -90,13 +121,55 @@ for _Dict in [:Dict, :OrderedDict]
90121 $($ DefaultDict) (default, d::AbstractDict; passkey=false)
91122 $($ DefaultDict) {K, V}(default, pairs...; passkey=false)
92123 $($ DefaultDict) {K, V}(default, dict::AbstractDict; passkey=false)
93-
94- Construct an $($ (_Dict == :Dict ? " un" : " " )) ordered dictionary from the given key-value `pairs` or `dict`
95- with a `default` value to be returned for keys that are not stored in the dictionary. The key and value
96- types may be optionally specified with the `K` and `V` parameters.
97-
98- If the `default` value is a `Function` or `Type`, then it will be _called_ upon the retrieval of a missing key,
99- with either 0 arguments (if `passkey==false`) or with the key that was requested.
124+
125+ Construct an $($ (_Dict == :Dict ? " un" : " " )) ordered dictionary with "default on miss" behavior.
126+ When accessing a missing key, the dictionary returns (and stores) either the constant
127+ `default` value (if non-callable) or the result of calling the callable `default`.
128+
129+ If the `default` is a `Function` or `Type`, it is called on retrieval of a missing key
130+ with either zero arguments (if `passkey==false`) or with the requested key (if `passkey==true`).
131+
132+ # Examples
133+ ```julia
134+ # Counting pattern with constant default
135+ counter = $($ DefaultDict) (0)
136+ for ch in "banana"
137+ counter[ch] += 1
138+ end
139+ # counter['b'] == 1, counter['a'] == 3, counter['n'] == 2
140+
141+ # Grouping items with fresh container per key
142+ groups = $($ DefaultDict) (() -> Int[])
143+ for (k, v) in [("a", 1), ("a", 2), ("b", 3)]
144+ push!(groups[k], v)
145+ end
146+ # groups["a"] == [1, 2], groups["b"] == [3]
147+
148+ # Using type constructors as callable defaults
149+ dd = $($ DefaultDict) (Vector{String})
150+ push!(dd[:colors], "red")
151+ push!(dd[:colors], "blue")
152+ # dd[:colors] == ["red", "blue"]
153+
154+ # passkey=false: default function called with no arguments
155+ dd1 = $($ DefaultDict) (() -> "default", passkey=false)
156+ dd1["anything"] # returns "default"
157+
158+ # passkey=true: default function receives the missing key
159+ dd2 = $($ DefaultDict) (k -> "Key '\$ k' not found", passkey=true)
160+ dd2["missing"] # returns "Key 'missing' not found"
161+ dd2["other"] # returns "Key 'other' not found"
162+
163+ # Initialize with specified types
164+ dd = $($ DefaultDict) {String,Int}(0)
165+ dd["a"] = 1
166+ dd["b"] # returns 0
167+
168+ # Create from existing dictionary
169+ base = Dict("a" => 1, "b" => 2)
170+ dd = $($ DefaultDict) (0, base)
171+ dd["c"] # returns 0
172+ ```
100173 """
101174 struct $ DefaultDict{K,V,F} <: AbstractDict{K,V}
102175 d:: DefaultDictBase{K,V,F,$_Dict{K,V}}
@@ -141,6 +214,20 @@ for _Dict in [:Dict, :OrderedDict]
141214 # calls setindex!
142215 @delegate_return_parent $ DefaultDict. d [ Base. delete!, Base. empty!, Base. setindex!, Base. sizehint! ]
143216
217+ """
218+ push!(d::$($ DefaultDict) , p::Pair)
219+ push!(d::$($ DefaultDict) , p::Pair...)
220+
221+ Insert one or more key-value pairs into the dictionary `d`.
222+
223+ # Examples
224+ ```jldoctest
225+ julia> d = $($ DefaultDict) (0)
226+ julia> push!(d, "a" => 1, "b" => 2)
227+ julia> d["a"]
228+ 1
229+ ```
230+ """
144231 # NOTE: The second and third definition of push! below are only
145232 # necessary for disambiguating with the fourth, fifth, and sixth
146233 # definitions of push! below.
@@ -154,7 +241,17 @@ for _Dict in [:Dict, :OrderedDict]
154241 Base. push! (d:: $DefaultDict , p, q) = push! (push! (d, p), q)
155242 Base. push! (d:: $DefaultDict , p, q, r... ) = push! (push! (push! (d, p), q), r... )
156243
244+ """
245+ empty(d::$($ DefaultDict) )
246+
247+ Return an empty $($ DefaultDict) with the same default value and type parameters.
248+ """
157249 Base. empty (d:: $DefaultDict{K,V,F} ) where {K,V,F} = $ DefaultDict {K,V,F} (d. d. default)
250+ """
251+ in(key, keys::Base.KeySet{K,$($ DefaultDict) {K}})
252+
253+ Check if `key` is present in the key set of a $($ DefaultDict) .
254+ """
158255 Base. in (key, v:: Base.KeySet{K,T} ) where {K,T<: $DefaultDict{K} } = key in keys (v. dict. d. d)
159256 end
160257end
0 commit comments