Florian Oswald
Florian Oswald

Reputation: 5144

How to use Julia map on a Dict of Dicts?

I want to iterate over a collection of dicts and evaluate a function that takes one Dict at a time. In R-speak I have a list of lists and want to lapply my function - which takes a list as input - for each sublist:

function dfun(d::Dict)
   println(collect(keys(d)))
   println(collect(values(d)))
   end

# my dict of dicts
d = [1 => ["a" => 1.1], 2 => ["b" => 3.12]]
[2=>["b"=>3.12],1=>["a"=>1.1]]

# works?
julia> dfun(d[1])
ASCIIString["a"]
[1.1]

# maps?
map(dfun,d)
ERROR: no method dfun((Int64,Dict{ASCIIString,Float64}))
 in map at abstractarray.jl:1183

What's the correct way of doing this? I'm surprised it sends (Int64,Dict{ASCIIString,Float64}) to the funciton and not just Dict{ASCIIString,Float64}

(sorry for crossposting - but i think SO is just so much nicer to search...)

Upvotes: 5

Views: 5962

Answers (2)

DSM
DSM

Reputation: 353604

In Julia, iteration over a dictionary is iteration over key/value pairs, not iteration over values (or iteration over keys, as in Python):

julia> for x in d println(x); println(typeof(x)) end
(2,["b"=>3.12])
(Int64,Dict{ASCIIString,Float64})
(1,["a"=>1.1])
(Int64,Dict{ASCIIString,Float64})

so that's why your map is getting (Int64,Dict{ASCIIString,Float64})-typed args. If you want the values, you could ask for those specifically:

julia> map(dfun, values(d))
ASCIIString["b"]
[3.12]
ASCIIString["a"]
[1.1]
2-element Array{Any,1}:
 nothing
 nothing

but if you're not returning anything from the function, it feels a little weird to use map because you're building an unneeded Array of nothing. I'd just do

julia> for v=values(d) dfun(v) end
ASCIIString["b"]
[3.12]
ASCIIString["a"]
[1.1]

Upvotes: 7

Florian Oswald
Florian Oswald

Reputation: 5144

got an answer on the mailing list:

map(dfun,values(d))

Upvotes: 3

Related Questions