2011-07-25 41 views
0

我有二維散列,我想打印出簡單的html表格。有像select section,date,count(*) from table group by section,date這樣的查詢,因此某些索引的值可能不存在。在ruby,ruby語法中使用零值打印表格

我的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>"; 
?> 

回答

1

有幾種方法,以避免它。一個最簡單的我能想到的就是更換:

<% 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]),則返回而不是。 (零|| ||)返回零(這是一個默認值,我假設)。

如果散列只包含數字,你也可以使用:

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

nil.to_i返回零。 (當心不過,「一些字符串」 .to_i也返回零。)

0

你可以嘗試手動附加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_procdefault_proc方法可能對您的特定需求太聰明,但一般的技術值得一提。

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

或默認值:

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

,將返回的最後一個值。請記住,&&做短路評估,並在紅寶石,只有零和虛假評估爲false。

這隻適用於如果中間值總是零或哈希...如果@rws[sec] == "foo",那麼它會給出一個錯誤。

我喜歡在少數情況下default_proc的解決方案,特別是對深哈希值,但它可能是矯枉過正的小用途...

0

你可以這樣做:

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