2014-01-08 10 views
6

Предположим, что я пишу функцию в Julia, которая принимает в качестве аргумента Dict{K,V}, а затем создает массивы типа Array{K,1} и Array{V,1}. Как я могу извлечь типы K и V из объекта Dict, чтобы я мог использовать их для создания массивов?Извлечение типов параметров в Julia

ответ

6

Ответы Свена и Джона оба совершенно правильные. Если вы не хотите, чтобы ввести параметры типа метода, как код Джона делает, вы можете использовать eltype функции:

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 

Как вы можете видеть, есть несколько способов кожи этого кота, но я думаю, что eltype(keys(d)) и eltype(values(d)) являются на сегодняшний день самыми ясными, и поскольку функции keys и values просто возвращают неизменные объекты вида, компилятор достаточно умен, что фактически не создает никаких объектов.

+0

Спасибо всем. Я решил принять этот ответ, потому что он был наиболее общим (также будет работать и с другими итерабельными структурами данных). –

+0

'eltype (d)' now возвращает 'Pair {ASCIIString, Int64}' и 'eltype (d) [1]' больше не работает. (Julia v0.4) – colinfang

+0

'keytype' и' valtype' являются встроенными с v0.4 и заменяются соответственно 'eltype (d) [1]' и 'eltype (d) [2]', соответственно , –

3

Вы можете использовать keys и values в сочетании с typeof:

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

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

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

Возможно, стоит отметить, что 'keys' и' values' теперь возвращают итераторы, а не массивы. Вам нужно добавить вызов «собирать» в новых версиях Julia, чтобы получить массив. –

7

Если вы пишете функцию, которая будет делать это для вас, вы можете сделать типы параметр функции, который может сохранить вы некоторое время просматриваете:

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

Если вы просто заинтересованы в типах, вы можете использовать eltype(d), или определить еще более конкретные функции

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

и найти тип сразу через

keytype(d) 
valuetype(d) 

Насколько я понимаю, это должно быть довольно эффективно, потому что компилятор может вывести большую часть этого во время компиляции.

Смежные вопросы