Anybody can show me the grammer for dict's dict in julia

question
#1

Hi, as I would like to use dict’s dict to storage and visiting data, but I can not find the correct grammar to stat the dict’s dict, initiate it and visiting it.

Can anybody give some examples about how to do it in julia? In perl, we use a lot similar features like hash’hash; hash’s array.

Thank you very much.

0 Likes

#2

I’m not sure if this is what you are requesting, maybe it is.
If you one entry and all keys share a type and all values share another type:

julia> dict = Dict([ 1 => "one", 2 => "two" ])
Dict{Int64,String} with 2 entries:
  2 => "two"
  1 => "one"

julia> dict[2]
"two"

julia> collect(keys(dict))
2-element Array{Int64,1}:
 2
 1

julia> collect(values(dict))
2-element Array{String,1}:
 "two"
 "one"

To update the dict


julia> dict[3] = "three"
"three"

julia> dict[1] = "One"
"One"

julia> collect(values(dict))
3-element Array{String,1}:
 "two"  
 "three"
 "One"  

There is much more flexibility too.
This is important reading:
https://docs.julialang.org/en/v1/base/collections/#Dictionaries-1

0 Likes

#3

This is just Dict, it is not dict’s dict

D1 = Dict(["a" => "b"])

D2 = Dict(["c" => "d"])

julia> dict = Dict([1  => D1, 2 => D2])
Dict{Int64,Dict{String,String}} with 2 entries:
  2 => Dict("c"=>"d")
  1 => Dict("a"=>"b")

julia> dict[1]["a"]
"b"

##init a dict's dict
julia> dic = Dict(String => Dict(String => String))
Dict{DataType,Dict{DataType,DataType}} with 1 entry:
  String => Dict(String=>String)

##assign value to it 
julia> dic["b"]["a"] = "This is a test of dict's dict"
ERROR: KeyError: key "b" not found
Stacktrace:
 [1] getindex(::Dict{DataType,Dict{DataType,DataType}}, ::String) at ./dict.jl:478
 [2] top-level scope at none:0

Errors here!!

0 Likes

#4
julia> dict = Dict()
Dict{Any,Any} with 0 entries

julia> dict["b"] = Dict("a" => "This is a test")
Dict{String,String} with 1 entry:
  "a" => "This is a test"

julia> dict["b"]["a"]
"This is a test"
0 Likes

#5

Maybe not totally related but maybe this helps

0 Likes

#6

Thanks

dicta = Dict()

dictb = Dict()

dicta["a"] = dictb

#init dictb with multi keys

dictb["c"] = "d"

dictb["e"] = "f"

dicta["a"]["c"] = "d"

dicta["a"]["e"] = "f"

It may work in this way. Not convenient at all! At perl, you can directly init dicta[“a”][“c”]

= “d”

and insert another key dicta[“a”][“e”] = “f”

Jeffrey Sarnoff via JuliaLang julialang@discoursemail.com 于2019年3月8日周五 下午8:02写道:

0 Likes

#7

You can use the DefaultDict from DataStructures.jl to accomplish this:

julia> dicta = DefaultDict(Dict)
DefaultDict{Any,Any,UnionAll} with 0 entries

julia> dicta["a"]["c"] = "d"
"d"

julia> dicta["a"]["e"] = "f"
"f"

julia> dicta
DefaultDict{Any,Any,UnionAll} with 1 entry:
  "a" => Dict{Any,Any}("c"=>"d","e"=>"f")

Please quote your code with ``` triple backtick “fences” to format it in a way that’s easier for folks to read (and copy-paste).

3 Likes

#8

Why not simply use Dict{String, Dict{String, String}}?

dic = Dict(
  "b" => Dict("a",  "This is a test of dict of dict")
)

default(::Type{Dict{K, V}}) where {K, V} = Dict{K, V}()
default(::Type{Int}) = 0
default(::Type{String}) = ""

setter(k) = v -> dic -> dic[k] = v

getter(k :: K) where K = function (dic :: Dict{K, V}) where V
   get!(dic, k) do
       default(V)
   end
end

set1(v) = setter("a")(v) \circ getter("b")
set1("dict.b.a")(dic)

set2(v) = setter("c")(v) \circ getter("b")
set2("dict.b.c")(dic)

0 Likes

#9

Thanks, this solution is works well and can work on the fly! Also for the tip of quote code with ```

0 Likes