Apply dictionary (Dict) to many keys at once (broadcast)

Given a simple dictionary d = Dict(1 => "a", 2 => "b", 3 => "c")

Is there a simple way to apply the dictionary to a list / vector / tuple of keys at once?

I would like to “translate” a vector of numbers into letters like
p = [1 3 2 1 2 1 3]

my current solutions include:

  1. using the get function: get.(Ref(d), p, 0)
  2. using a map function:
map(p) do x
  d[x]
end
  1. using a comprehension
    [d[x] for x in p]
  2. or writing an eval function (for short hand notation)
    dict_eval(dict, key) = get.(Ref(dict), key, 0)
    using
    dict_eval(d,p)

Do you have a suggestions for a better (short and fast = elegant) solution?

Concerning the syntax: My intuition would say that I would broadcast a dictionary to a vector of keys with a syntax like
d.[p]
but this is not (yet) a valid syntax in Julia.

Maybe this relates to the github issue 30836?

I am looking for a short syntax as this would help a lot in applying multiple dictionaries sequentially at once like (just think of encrypting text with different dictionaries like Caesar cypher)
caesar = Dict("a" => "d", "b" => "e", "c" => "f")

caesar.[d.[p]]

Dictionaries can readily be considered as functions with a finite domain. Thus, arguably, they should be callable anyways:

(d::Dict)(k) = d[k]

and caesar.(d.(p)) just works as expected.

4 Likes

This is so useful.
Why aren’t the Dicts shipped like this from the factory?

That’s exactly what I thought about any other language after seeing that dictionaries and vectors are callable in Clojure. It just feels correct.

1 Like