用ruby、ruby语法打印具有零值的表



我有二维哈希,我想打印出一个简单的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>";
?>

有几种方法可以避免它。我能想到的最简单的方法是替换:

    <% 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返回零。(不过要注意,"some string".to_i也返回零。(

您可以尝试在控制器内手动将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?]

它会起作用的。不利的一面是,当你要求一些不存在的东西时,你总是会得到一个空散列,所以你可能不得不在通常会调用nil?的地方调用emtpy?。所以你会有这样的东西:

<% 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方法对于您的特定需求来说可能太聪明了,但一般技术值得一提。

<%= @rws && @rws[sec] && @rws[sec][date] %>

或具有默认值:

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

这将返回最后一个值。请记住,&&进行短路求值,在ruby中,只有nil和false求值为false。

只有当中间值始终为零或为散列时,这才有效。。。如果@rws[sec] == "foo",则它将给出错误。

在某些情况下,我喜欢default_proc解决方案,尤其是对于深度哈希,但对于小的使用来说,它可能有些过头了。。。

您可以这样做:

<% sections.each do sec %>
    <tr>
    <% dates.each do date %>
        <td><%= @rws[sec][date] rescue 0 %></td>
    <% end %>
    </tr>
<% end %> 

相关内容

  • 没有找到相关文章