I would like to broadcast an operation to all values of a dictionary. For an array, I know I can broadcast an element-wise operation using:
julia> b1 = [1, 2, 3]
julia> b1./2
3-element Array{Float64,1}:
0.5
1.0
1.5
What is an efficient way of broadcasting the same operation to all values of a dictionary? Say, for the dictionary
a1 = Dict("A"=>1, "B"=>2)
An iteration protocol is defined for both keys and values of dictionaries, so you can just do, eg:
julia> d = Dict("a"=>1, "b"=>2)
Dict{String,Int64} with 2 entries:
"b" => 2
"a" => 1
julia> values(d).^2
2-element Array{Int64,1}:
4
1
If you want to alter the dictionary in-place, use map!
, eg:
julia> map!(x->x^2, values(d))
Base.ValueIterator for a Dict{String,Int64} with 2 entries. Values:
4
1
julia> d
Dict{String,Int64} with 2 entries:
"b" => 4
"a" => 1
However, your function must output a type that can be converted back to the dictionary value type. In my example, I'm squaring Int
which yields Int
. However, in the question you are dividing by 2, which obviously yields Float64
. If the float cannot be converted back to an integer, then you'll get an error.
Note, you can broadcast over keys also, e.g.:
julia> f(x) = "hello mr $(x)"
f (generic function with 1 method)
julia> f.(keys(d))
2-element Array{String,1}:
"hello mr b"
"hello mr a"
but this can not be done in-place, i.e. you can't use map!
on keys.
Importantly, note that you should not instantiate the collection. Indeed, this would be inefficient. So avoid constructs like: collect(values(d)) ./ 2
.