Печать таблиц с нулевыми значениями в ruby, синтаксис ruby - PullRequest
0 голосов
/ 25 июля 2011

У меня есть двумерный хэш, и я хочу напечатать его в простой HTML-таблице.Был запрос типа select section,date,count(*) from table group by section,date, поэтому значения для некоторых индексов могут не существовать.

Мой код ruby ​​выглядит как

<% sections.each do sec %>
    <tr>
    <% dates.each do date %>
        <% v = 0 %>
        <% v = @rws[sec][date] unless @rws.nil? || @rws[sec].nil? || @rws[sec][date].nil? %>
        <td><%=v%></td>
    <% end %>
    </tr>
<% end %> 

Есть ли лучший способ работы с многомерным хэшембесконечные проверки вроде do something with a unless a.nil? || a[b].nil? || a[b][c].nil? || a[b][c][d].nil? ...?

Например, в php я просто пишу:

<?php 
    foreach($sections as $sec)
        foreach($dates as $date)
            echo "<td>" . ($rws[$sec][$date]?$rws[$sec][$date]:0) . "</td>";
?>

Ответы [ 4 ]

1 голос
/ 25 июля 2011

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

    <% v = 0 %>
    <% v = @rws[sec][date] unless @rws.nil? || @rws[sec].nil? || @rws[sec][date].nil? %>
    <td><%=v%></td>

следующим:

    <td><%= (@rws[sec][date] rescue nil) || 0 %></td>

Что означает: отображать содержимое хэша.если по какой-то причине возникнет исключение (например, вызов nil [date]), вместо этого верните nil .(nil || 0) возвращает ноль (я полагаю, это значение по умолчанию).

Если хеш содержит только цифры, вы также можете использовать:

    <td><%= (@rws[sec][date] rescue nil).to_i %></td>

nil.to_i возвращаетнуль.(Обратите внимание, что "некоторая строка" .to_i также возвращает ноль.)

0 голосов
/ 25 июля 2011

Вы можете сделать это:

<% sections.each do sec %>
    <tr>
    <% dates.each do date %>
        <td><%= @rws[sec][date] rescue 0 %></td>
    <% end %>
    </tr>
<% end %> 
0 голосов
/ 25 июля 2011
<%= @rws && @rws[sec] && @rws[sec][date] %>

или со значением по умолчанию:

<%= (@rws && @rws[sec] && @rws[sec][date]) || 0 %>

Это вернет последнее значение. Помните, что && выполняет оценку короткого замыкания, а в ruby ​​только nil и false оцениваются как false.

Это работает только в том случае, если промежуточные значения всегда равны нулю или хэшу ... если @rws[sec] == "foo", то это даст ошибку.

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

0 голосов
/ 25 июля 2011

Вы можете попробовать вручную присоединить default_proc к вашему @rws внутри контроллера:

@rws = pile_of_stuff_that_produces_a_hash
@rws.default_proc = proc do |h,k|
    x = { }
    x.default_proc = @rws.default_proc
    h[k] = x
    x
end

Обратите внимание, что default_proc является "унаследованным" (x.default_proc = @rws.default_proc) недавно созданными хешами, чтобы вы получали новые хеши полностью вниз.Тогда вы можете сделать это:

@rws[:where][:is][:pancakes][:house?]

И это сработает.Недостатком является то, что вы всегда будете получать пустой хеш, когда просите что-то, чего не было, поэтому вам, возможно, придется звонить emtpy? в тех местах, где вы обычно звоните nil?.Таким образом, у вас будет что-то вроде этого:

<% dates.each do date %>
    <% v = @rws[sec][date] %>
    <td><%= v.is_a?(Hash) && v.empty?? 0 : v %></td>
<% end %>

В зависимости от ваших конкретных обстоятельств, вы можете урезать v.is_a?(Hash) && v.empty? до чего-то более приятного;например, если @rws должны быть числами до конца, то v.is_a?(Hash) будет достаточно.

Этот default_proc подход может быть слишком умным для ваших конкретных нужд, но стоит упомянуть общую технику.

...