Dictionary 生成包含范围的所有词典组合

Dictionary 生成包含范围的所有词典组合,dictionary,range,julia,Dictionary,Range,Julia,在julia中,我有一个字典,可以包含其他字典、字符串/数字列表、字典列表、字符串/数字和范围 我需要一个列表,其中包含它所包含的每个范围(如StepRange、FloatRange、UnitRange)的所有可能的字典组合 例如: Dict{}("A" => Dict{}("B" => 1:1:3, "C" => 2), "B" => [Dict{}( "S" => 1:1.1:2.1)]) => 现在,我正在重载这样的递归函数,但不知道如何继续 functio

在julia中,我有一个字典,可以包含其他字典、字符串/数字列表、字典列表、字符串/数字和范围

我需要一个列表,其中包含它所包含的每个范围(如StepRange、FloatRange、UnitRange)的所有可能的字典组合

例如:

Dict{}("A" => Dict{}("B" => 1:1:3, "C" => 2), "B" => [Dict{}( "S" => 1:1.1:2.1)])
=>

现在,我正在重载这样的递归函数,但不知道如何继续

function iterate(generic, nets::Array)
    return (generic, false)
end

function iterate(range::Union{StepRange,FloatRange,UnitRange}, nets::Array)
    return (collect(range), true)
end

function iterate(array::Array, nets::Array)
    for (n, v) in enumerate(array)
        res = iterate(v, nets)
        if res[2]
            ## We found a range! Return it
            return res
        end
    end
    return (array, false)
end

function iterate(dict::Dict, nets::Array)
    for (k, v) in dict
        res = iterate(v, nets)
        if res[2]
            return (dict, true)
        end
    end
    return (dict, false)
end

(我已经在python中完成了这项工作,但正在处理一段文本,使用正则表达式查找自定义定义的范围(如“[1,2,0.1]”),并在生成文本代码对其进行解析之后。)

下面的代码段再现了示例中的输出,它可以作为其他变量的基础,这些变量以不同的方式处理递归(正如我在尝试此功能时所注意到的,有很多选项)。它使用
Iterators.jl
安装在
Pkg.add(“Iterators”)

举个例子:

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))

在这个例子中,
“B”=>1:1:3
,而输出只列出
“B”=>1
“B”=2
,而不是
“B”=>3
。这是一个错误/打字错误吗?(因为
收集(1:1:3)=[1,2,3]
)修正了,抱歉。我讨厌stackoverflow文本编辑器,希望尽快摆脱它:DOn我必须添加的真实示例:recdictcollect(sd::Int)=sd,但这确实奏效了!谢谢
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
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))