JSON3 to mutable Dict{String,Any}

I’m using JSON3 to parse an input that can be either a json or an array of json string. I want to convert the output of JSON3.read to either a mutable Dict{String,Any} or Array{Dict{String,Any}}, respectively. I see that copy(JSON3.read(...)) always returns keys as Symbol and not String. The only solution I have so far to return keys as String is to using a sink argument that is a union: JSON3.read(input,Union{Dict{String,Any},Array{Dict{String,Any}}}). Anyone know of a preferred way to do this or is this the way to go?

I’ll provide a MWE below to play with:

using JSON3

# create input to play with
d1 = Dict("a"=>1, :b=>Dict("c"=>2, :d=>3))
d2 = [Dict("a"=>1, :b=>Dict("c"=>2, :d=>3)) for _ in 1:2]

# create json strings of the input 
d1_json = JSON3.write(d1)
d2_json = JSON3.write(d2)

# returns a Dic{Symbol,Any} and Vector{Dict{Symbol,Any}} but not String as keys   
d12 = copy(JSON3.read(d1_json))
d22 = copy(JSON3.read(d2_json))

# returns String as keys but is this the right way to go?
d13 = JSON3.read(d1_json,Union{Dict{String,Any},Array{Dict{String,Any}}})
d23 = JSON3.read(d2_json,Union{Dict{String,Any},Array{Dict{String,Any}}})

That looks to be about the best you can do at the moment. I’m working on something that would make this much more straightforward, but it’s not quite ready for public consumption yet.

1 Like


1 Like

Thanks for the advice. JSON was my first attempt but it did not handle nested jsons well so I tried JSON3 and that did it without any issues or workarounds. I also liked that I can access JSON3 object’s fields in may ways, however, when I convert it to a mutable object that functionality was lost and I needed keys as String.