4

I was wondering if there was an efficient ("canonical") way to traverse a dictionary with a JSON like structure. For example, I have a dictionary with an array of dictionaries that sometimes don't have the same keys. I then need to iterate over these dictionaries and check if an specific key has a certain value. For example:

for cell in cells
  if cell["key1"]["key2"]["key3"] == true
     # do stuff
  end
end

The issue is that sometimes the cell won't have either "key1", or "key2" or "key3", so a simple get(cell, key1, false) won't work. Of course, I could always write a bunch of if statements, but I was wondering if there was a smarter and more direct way of doing this.

Davi Barreira
  • 1,597
  • 11
  • 19

1 Answers1

4

Define your own operator!

▷(d::Dict{K,V}, k::K2) where {K, V, K2<:K} = get(d, k, nothing)
▷(d::Dict{K,V}, k::Symbol) where {K, V} = get(d, k, d ▷ string(k))
▷(::Nothing, k::K2) where K2 = nothing

In my code the Symbol version is for convenience.

Now let us do the setup:

cellA = Dict("key1"=>Dict("key2"=>Dict("key3"=>true)))
cellBad = Dict("key1"=>Dict("keyBad"=>Dict("key3"=>true)))

Let's use this new API:

julia> cellA ▷ :key1 ▷ :key2 ▷ :key3
true

julia> cellA ▷ :key1 ▷ :key2 ▷ :key3  == true
true

julia> cellBad ▷ :key1 ▷ :key2 ▷ :key3

julia> cellBad ▷ :key1 ▷ :key2 ▷ :key3 == true
false

See the list of available operators and their precedence at User-defined infix operator

Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62