Question: Is there a function to flatten a nested dictionary?

Hi everyone, I’m facing the following problem: Suppose I have a nested dictionary like

data = Dict(
    "id"   => 42,
    "name" => Dict("first" => "John", "last" => "Doe", "nick" => nothing))

which I want to flatten into:

data_flat = Dict(
    "id"         => 42,
    "name.first" => "John",
    "name.last"  => "Doe",
    "name.nick"  => nothing
)

My question is the following: Is there function that does this? Something like flatten_dict(dict, sep="."), or would I have to solve this manually by looping through my nested data? I looked trough the JSON.jl package but either there is no such thing or I missed it.

I am not sure if there is something that fits your exact need, but it does not seem something so hard to implement.

function rec_flatten_dict(d, prefix_delim = ".")
    new_d = empty(d)
    for (key, value) in pairs(d)
        if isa(value, Dict)
             flattened_value = rec_flatten_dict(value, prefix_delim)
             for (ikey, ivalue) in pairs(flattened_value)
                 new_d["$key.$ikey"] = ivalue
             end
        else
            new_d[key] = value
        end
    end
    return new_d
end

Creates some intermediary structs, so it is not a solution with the greatest performance, but it does the job.

julia> rec_flatten_dict(data)
Dict{String,Any} with 4 entries:
  "name.last"  => "Doe"
  "name.nick"  => nothing
  "name.first" => "John"
  "id"         => 42
6 Likes

Since this doesn’t work in place, you could change the recursion like s:

if isa(value, Dict)
             flattened_value = rec_flatten_dict(value, prefix_delim)
             for (ikey, ivalue) in pairs(flattened_value)
                 new_d["$key.$ikey"] = ivalue
             end
        else
2 Likes

Well spotted, I will fix it.

Thank you for your answer, and for even providing working code! I thought before I try to do it manually I should ask if I missed something that’s already available.