The following snippet reproduces the result in the example, and it can serve as the basis for other options that relate to recursion differently (there are many options, as I noticed when trying this). It uses Iterators.jl , which is installed with Pkg.add("Iterators") .
using Iterators function findranges{K}(sd::Dict{K}) ranges = Vector{Vector}() for v in values(sd) if isa(v,Range) push!(ranges,collect(v)) elseif isa(v,Dict) push!(ranges,recdictcollect(v)) elseif isa(v,Vector) push!(ranges,map(x->vcat(x...),collect(product(map(recdictcollect,v)...)))) end end ranges end function recdictcollect{K}(sd::Dict{K}) ranges = findranges(sd) if length(ranges)==0 cases = [()] else cases = product(ranges...) |> collect end outv = Vector{Dict{K,Any}}() for c in cases newd = Dict{K,Any}() i = 1 for (k,v) in sd if any([isa(v,t) for t in [Range,Dict,Vector]]) newd[k] = c[i] i += 1 else newd[k] = v end end push!(outv,newd) end return outv end
And an example:
julia> example = Dict{}("A" => Dict{}("B" => 1:1:3, "C" => 2), "B" => [Dict{}( "S" => 1:1.1:2.1)]) Dict{ASCIIString,Any} with 2 entries: "B" => [Dict("S"=>1.0:1.1:2.1)] "A" => Dict{ASCIIString,Any}("B"=>1:1:3,"C"=>2) julia> recdictcollect(example) 6-element Array{Dict{ASCIIString,Any},1}: Dict{ASCIIString,Any}("B"=>[Dict{ASCIIString,Any}("S"=>1.0)],"A"=>Dict{ASCIIString,Any}("B"=>1,"C"=>2)) Dict{ASCIIString,Any}("B"=>[Dict{ASCIIString,Any}("S"=>2.1)],"A"=>Dict{ASCIIString,Any}("B"=>1,"C"=>2)) Dict{ASCIIString,Any}("B"=>[Dict{ASCIIString,Any}("S"=>1.0)],"A"=>Dict{ASCIIString,Any}("B"=>2,"C"=>2)) Dict{ASCIIString,Any}("B"=>[Dict{ASCIIString,Any}("S"=>2.1)],"A"=>Dict{ASCIIString,Any}("B"=>2,"C"=>2)) Dict{ASCIIString,Any}("B"=>[Dict{ASCIIString,Any}("S"=>1.0)],"A"=>Dict{ASCIIString,Any}("B"=>3,"C"=>2)) Dict{ASCIIString,Any}("B"=>[Dict{ASCIIString,Any}("S"=>2.1)],"A"=>Dict{ASCIIString,Any}("B"=>3,"C"=>2))