/ / Uzyskiwanie wartości skrótu ruby ​​za pomocą tablicy kluczy - ruby ​​na szynach, ruby, tablice, skrót

Uzyskanie wartości mieszania ruby ​​za pomocą szeregu kluczy - ruby-on-rails, ruby, tablice, hash

To, co zamierzam zrobić, to stworzyć obiektktóry jest inicjowany za pomocą skrótu, a następnie odpytuje ten obiekt, aby uzyskać wartości z tego skrótu. Aby to wyjaśnić, oto przybliżony przykład tego, co mam na myśli:

class HashHolder
def initialize(hash)
@hash = hash
end

def get_value(*args)
# What are my possibilities here?
end
end

holder = HashHolder.new({:a => { :b => { :c => "value" } } } )
holder.get_value(:a, :b, :c) # should return "value"

Wiem, że mogę wykonać iterację na liście argumentów jak w:

def get_value(*args)
value = @hash
args.each do |k|
value = value[k]
end
return value
end

Ale jeśli planuję dużo korzystać z tej metody, dramatycznie obniży to moją wydajność, gdy wszystko, co chcę zrobić, to uzyskać dostęp do wartości skrótu.

Jakieś sugestie na ten temat?

Odpowiedzi:

7 dla odpowiedzi № 1

Aby zaktualizować odpowiedź, ponieważ minęło już trochę czasu od momentu jej pytania.

(testowane w Ruby 2.3.1)

Masz taki skrót:

my_hash = {:a => { :b => { :c => "value" } } }

Pytanie zadane:

my_hash.get_value(:a, :b, :c) # should return "value"

Odpowiedź: Użyj „dig” zamiast get_value, na przykład:

my_hash.dig(:a,:b,:c) # returns "value"

Ponieważ tytuł pytania wprowadza w błąd (powinno to być coś w rodzaju: jak uzyskać wartość w zagnieżdżonym haszu za pomocą tablicy kluczy), oto odpowiedź na pytanie, które faktycznie zostało zadane:

Uzyskiwanie wartości skrótu ruby ​​za pomocą tablicy kluczy

Przygotowanie:

my_hash = {:a => 1, :b => 3, :d => 6}
my_array = [:a,:d]

Odpowiedź:

my_hash.values_at(*my_array) #returns [1,6]

4 dla odpowiedzi nr 2
def get_value(*args)
args.inject(@hash, &:fetch)
end


Jeśli chcesz uniknąć iteracji podczas wyszukiwania (co nie wydaje mi się konieczne), musisz spłaszczyć skrót, który ma być przechowywany:

class HashHolder
def initialize(hash)
while hash.values.any?{|v| v.kind_of?(Hash)}
hash.to_a.each{|k, v| if v.kind_of?(Hash); hash.delete(k).each{|kk, vv| hash[[*k, kk]] = vv} end}
end
@hash = hash
end
def get_value(*args)
@hash[args]
end
end

-3 dla odpowiedzi № 3

Jeśli wiesz, że struktura skrótu jest zawsze w tym formacie, możesz po prostu zrobić:

holder[:a][:b][:c]

... zwraca „wartość”.