2016-12-13 4 views
0

У меня есть плоская структура данных в формате csv, в которой я превратился в хэш, в котором задан ключ на одном из столбцов в файле ... поэтому у нас есть key_1, key_2, Key_3, каждый ключ имеет соответствующие значения для соответствующей строкиДоступ к вложенной карте хеша в Ruby

Это является примером плоского файла ...

key  book id ccy mtm  161205 161206 161207 161208 161209 
key_1 abc 123 usd 2000000 -5045 600 494 -2646 -231 
key_2 abc 124 gbp -150000 5178 20669 -1871 214 22251 
key_3 abc 125 eur 1908055 -23279 -730 -513 -19933 -21555 

И это он после того, как я создаю хэш ...

{"key_1"=> 
    [{:book=>"abc", 
    :trade_id=>"123", 
    :ccy=>"usd", 
    :mtm=>2000000, 
    :"161205"=>-5045, 
    :"161206"=>600, 
    :"161207"=>494, 
    :"161208"=>-2646, 
    :"161209"=>-231}], 
"key_2"=> 
    [{:book=>"abc", 
    :trade_id=>"124", 
    :ccy=>"gbp", 
    :mtm=>-150000, 
    :"161205"=>5178, 
    :"161206"=>20669, 
    :"161207"=>-18771, 
    :"161208"=>214, 
    :"161209"=>22251}], 
"key_3"=> 
    [{:book=>"abc", 
    :trade_id=>"125", 
    :ccy=>"eur", 
    :mtm=>1908055, 
    :"161205"=>-23279, 
    :"161206"=>-730, 
    :"161207"=>-513, 
    :"161208"=>19933, 
    :"161209"=>-21555}]} 

Проблема, с которой я сталкиваюсь что я не могу получить доступ к вложенному хешу. Я хотел бы иметь возможность просверлить в хэш ... так что-то вроде этого ...

p h.select { |key| key == "key_3" } [ :ccy, :mtm " ] 

дал бы мне выход, как ...

[{"eur","1908055"}] 

Я также хотел бы быть способный делать такие вещи, как агрегация по ключам.

ответ

1
a['key_3']    # [{:book=>"abc", :trade_id=>"125", :ccy=>"eur", :mtm=>1908055, :"161205"=>-23279, :"161206"=>-730, :"161207"=>-513, :"161208"=>19933, :"161209"=>-21555}] 
    .first     # {:book=>"abc", :trade_id=>"125", :ccy=>"eur", :mtm=>1908055, :"161205"=>-23279, :"161206"=>-730, :"161207"=>-513, :"161208"=>19933, :"161209"=>-21555} 
    .values_at(:ccy, :mtm) # ["eur", 1908055] 
#=> ["eur", 1908055] 

EDIT

Чтобы пройти хэш и карту с помощью вложенного ключа использования Enumerable#map:

a.map { |_k, v| v.first[:mtm] } 
#=> [2000000, -150000, 1908055] 
a.map {|k, v| v.first[:"161205"]} 
#=> [-5045, 5178, -23279] 

P.S.

{"eur","1908055"} не является допустимым объектом в Ruby.

+0

Это работает! Благодарю. Можно ли использовать аналогичный метод для доступа ко всем клавишам и вытащить данные? – antimuon

+0

@antimuon конечно, позвольте мне отредактировать ответ –

+1

@antimuon отредактирован, дайте мне знать, если это помогло –

-2

Ваш внутренний хэш находится внутри массива.

first будет получает первый элемент массива

h['key_3'].first.values_at(:ccy, :mtm) может работать.

0

перебрать все ключи, книги и атрибуты:

h.each do |key, books| 
    puts key 
    books.each do |book| 
    # Use values_at to define variables 
    name, trade_id, price, currency = book.values_at(:book, :trade_id, :mtm, :ccy) 

    puts "#{name} : #{price} #{currency} (#{trade_id})" 

    # or iterate over all key/values : 
    book.each do |attribute, value| 
     puts "#{attribute} : #{value}" 
    end 

    puts 
    end 
end 

Он выводит:

key_1 
abc : 2000000 usd (123) 
book : abc 
trade_id : 123 
ccy : usd 
mtm : 2000000 
161205 : -5045 
161206 : 600 
161207 : 494 
161208 : -2646 
161209 : -231 

key_2 
abc : -150000 gbp (124) 
book : abc 
trade_id : 124 
ccy : gbp 
mtm : -150000 
161205 : 5178 
161206 : 20669 
161207 : -18771 
161208 : 214 
161209 : 22251 

key_3 
abc : 1908055 eur (125) 
book : abc 
trade_id : 125 
ccy : eur 
mtm : 1908055 
161205 : -23279 
161206 : -730 
161207 : -513 
161208 : 19933 
161209 : -21555 

Получите одно значение, вложенное в хэши/Массивы:

Это идеальная работа для dig, если вы используете Ruby 2.3:

h.dig("key_3", 0, :ccy) # => "eur" 
h.dig("key_3", 0, :mtm) # => 1908055 

Это «сверла» через хэши и массивы, и вам не придется беспокоиться об ошибках, если объект не найден:

h.dig("key_4", 0, :ccy) # => nil 

Вы можете комбинировать его с values_at и &. для безопасной навигации и несколько значений. Исключить не следует, если объект не найден:

h.dig("key_3", 0)&.values_at(:ccy, :mtm) #=> ["eur", 1908055] 
price, currency = h.dig("key_3", 0)&.values_at(:mtm, :ccy) 
price # => 1908055 
currency # => "eur" 
+0

dig хорошо, но AFAIK не будет делать, чтобы возвращать значения на несколько клавиш (': ccy,: mtm ...') –

+0

True. Я обновил пример с помощью '& .' и' values_at'. Благодарю. –

+0

Я использую 2.25, поэтому я не могу использовать dig, но я проведу проверку с 2.3. – antimuon

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