2017-02-14 9 views
0

У меня есть массив хешей, сохраненных в базе данных. Даты указаны в формате DateTime.Ruby - Array of Hashes - Найти значение from DateTime Key

@item.yearly_interest_totals = [ 
    {"financial_year" => "Sun, 01 Jan 2017 00:00:00 +0000", "total" => "360"}, 
    {"financial_year" => "Mon, 01 Jan 2018 00:00:00 +0000", "total" => "240"}, 
    {"financial_year" => "Tue, 01 Jan 2019 00:00:00 +0000", "total" => "240"} 
] 

На мой взгляд, у меня есть определенный финансовый год в переменной financial_year

Как я могу отобразить соответствующее значение с financial_year ключом? Я немного запутался о сравнении год число финансовых на объект DateTime ...

Например:

<tr> 
     <td>Financial Year: <%= financial_year.to_i %></td> 
     <td><%= @item.yearly_interest_totals.find{|i| i["financial_year"] == DateTime.new(financial_year.to_i,1,1)}["total"] %></td> 
</tr> 

Это должно отображаться как:

Финансовый год: 2017 360

FYI: Рельсы 5.0.0.1, Ruby 2.3.1, Local Postgres DB

ответ

0
financial_year = 2018 
yearly_interest_totals.map do |t| 
    t["total"] if Date.parse(t["financial_year"]).year == financial_year 
end.compact 
#⇒ ["240"] 

yearly_interest_totals.detect do |t| 
    Date.parse(t["financial_year"]).year == financial_year 
end["total"] 
#⇒ "240" 
0

Предполагая, что:

financial_year = 2017 

, то вы можете сделать:

@items.yearly_interest_totals.each do |yit| 
    yit.merge!(DateTime.strptime(yit['financial_year'], "%a, %d %b %Y %H:%M:%S %z").year => yit['total']) 
end 
#=>[ 
# {"financial_year"=>"Sun, 01 Jan 2017 00:00:00 +0000", "total"=>"360", 2017=>"360"}, 
# {"financial_year"=>"Mon, 01 Jan 2018 00:00:00 +0000", "total"=>"240", 2018=>"240"}, 
# {"financial_year"=>"Tue, 01 Jan 2019 00:00:00 +0000", "total"=>"240", 2019=>"240"} 
# ] 

Теперь на ваш взгляд:

<tr> 
    <td>Financial Year: <%= financial_year %></td> 
    <td><%= @item.yearly_interest_totals.find{|yit| yit[financial_year] }[financial_year] %></td> 
</tr> 

Обратите внимание, что я предполагаю, что вы показываете это в другом цикле финансовых лет, то выше решение делает время сложность O (n2), которая не является эффективным подходом, в противном случае она работает.


Если мы можем изменить этот массив в хэш хэш, то он может работать гораздо лучше для больших наборов данных:

yearly_interest_totals = @items.yearly_interest_totals.each_with_object({}) do |yit, obj| 
    obj[DateTime.strptime(yit['financial_year'], "%a, %d %b %Y %H:%M:%S %z").year] = yit 
end 
# => 
# { 
# 2017=>{"financial_year"=>"Sun, 01 Jan 2017 00:00:00 +0000", "total"=>"360"}, 
# 2018=>{"financial_year"=>"Mon, 01 Jan 2018 00:00:00 +0000", "total"=>"240"}, 
# 2019=>{"financial_year"=>"Tue, 01 Jan 2019 00:00:00 +0000", "total"=>"240"} 
# } 

Теперь на ваш взгляд:

<tr> 
    <td>Financial Year: <%= financial_year %></td> 
    <td><%= yearly_interest_totals[financial_year]['total'] %></td> 
</tr> 

Если вы имеют несколько финансовых данных за год, тогда я бы предположил, что у вас есть значение yearly_interest_totals хэш в виде массива или обновить общее количество (в зависимости от того, что работает).