2014-01-08 2 views
6

Angenommen, ich schreibe eine Funktion in Julia, die ein Dict{K,V} als Argument verwendet, dann erstellt Arrays vom Typ Array{K,1} und Array{V,1}. Wie kann ich die Typen K und V aus dem Dict-Objekt extrahieren, damit ich sie zum Erstellen der Arrays verwenden kann?Extrahieren von Parametertypen in Julia

Antwort

6

Sven und Johns Antworten sind beide ganz richtig. Wenn Sie keine Methode Typ Parameter, die die Art und Weise Johns Code tut einführen wollen, können Sie die eltype Funktion:

julia> d = ["foo"=>1, "bar"=>2] 
["foo"=>1,"bar"=>2] 

julia> eltype(d) 
(ASCIIString,Int64) 

julia> eltype(d)[1] 
ASCIIString (constructor with 1 method) 

julia> eltype(d)[2] 
Int64 

julia> eltype(keys(d)) 
ASCIIString (constructor with 1 method) 

julia> eltype(values(d)) 
Int64 

Wie Sie sehen können, gibt es ein paar Möglichkeiten, diese Katze Haut, aber ich denke, und eltype(values(d)) sind bei weitem die klarsten und seit die keys und values Funktionen einfach unveränderliche Ansicht Objekte zurückgeben, ist der Compiler schlau genug, dass dies tatsächlich keine Objekte erstellt.

+0

Danke allen. Ich habe mich entschieden, diese Antwort zu akzeptieren, weil sie am allgemeinsten war (sie wird auch an anderen iterierbaren Datenstrukturen arbeiten). –

+0

'eltype (d)' gibt nun 'Pair {ASCIIString, Int64}' und 'eltype (d) [1]' nicht mehr aus. (Julia v0.4) – colinfang

+0

'keytype' und' valtype' sind eingebaute Variablen ab v0.4, und ersetzen "eltype (d) [1]" bzw. "eltype (d) [2]" . –

3

Sie können mit typeofkeys und values in Kombination verwenden:

# an example Dict{K, V} 
d = Dict{Int64, ASCIIString}() 

# K 
typeof(keys(d)) 
Array{Int64,1} 

# V 
typeof(values(d)) 
Array{ASCIIString,1} 
+1

Vielleicht ist es wichtig zu wissen, dass 'keys' und' values' nun Iteratoren und keine Arrays zurückgeben. Sie müssen in neueren Versionen von Julia einen Aufruf von 'collect' hinzufügen, um ein Array zu entfernen. –

7

Wenn Sie eine Funktion schreiben, welcher sich dies für Sie tun, Sie die Typen ein Parameter der Funktion machen, die sparen können Sie einige Laufzeit-Lookups:

julia> function foo{K, V}(d::Dict{K, V}, n::Integer = 0) 
      keyarray = Array(K, n) 
      valarray = Array(V, n) 
      # MAGIC HAPPENS 
      return keyarray, valarray 
     end 
foo (generic function with 2 methods) 

julia> x, y = foo(["a" => 2, "b" => 3]) 
([],[]) 

julia> typeof(x) 
Array{ASCIIString,1} 

julia> typeof(y) 
Array{Int64,1} 
2

Wenn Sie sind nur interessiert an den Typen, können Sie eltype(d) verwenden, oder definieren noch spezifischere Funktionen

keytype{K}(d::Dict{K}) = K 
valuetype{K,V}(d::Dict{K,V}) = V 

und finden Sie den Typ sofort durch

keytype(d) 
valuetype(d) 

Soweit ich verstehe, Dies sollte ziemlich effizient sein, da der Compiler das meiste zur Kompilierzeit ableiten kann.