`if acct.activity[year] && acct.activity[year][month]` 是什么意思?

What does `if acct.activity[year] && acct.activity[year][month]` mean?

我正在尝试理解已不在场的某人编写的一行代码:

- if acct.activity[year] && acct.activity[year][month]

它在以下上下文中使用:

    %tbody
  - x = (@today.year == year) ? @today.month : 12
  - x.downto(1) do |month|
    %tr
      - if month == x
        %td{rowspan: x}= year
      %td= Date::MONTHNAMES[month]
      - @customer.accounts.each do |acct|
        - if acct.activity[year] && acct.activity[year][month]
          %td{'data-transactions' => acct.activity[year][month]}
            - stmt = acct.statement(year, month)
            = link_to 'View', url(:statements, :show, id: stmt.to_s)
            = link_to image_tag('/icons/document-pdf.png', alt: 'Download PDF'), url(:statements, :show, id: stmt, format: :pdf), class: :pdf
        - else
          %td

这段代码的目的是按月和年显示财务报表。奇怪的是我可以在我的控制台中输出数据,它采用这种形式;

{10=>1}
1
{3=>2}
2
{6=>1}
1
{6=>1, 9=>1}
1
{7=>2}
2
{3=>1}
1
{2=>1}
1
{2=>1, 4=>1}
1
{2=>1, 4=>1, 8=>2}
2
{4=>1}
1
{4=>1, 5=>1}
1
{4=>1, 5=>1, 6=>1}
1
{4=>1, 5=>1, 6=>1, 7=>14}
14

它在那里,但由于某种原因没有被归还。我们在使用 db 调用存储过程时让它工作,但是我们正在将项目更改为使用 API 和 HTTP 调用,从那以后它就不起作用了。这是它的声明和 puts 在控制台中生成以上内容的地方:

@activity = {}
@activity = response['AccountActivity'].map do |row|
  @activity[row['year']] = {} unless @activity[row['year']]
  @activity[row['year']][row['month']] = row['transactions']
  puts @activity[row['year']]
  puts @activity[row['year']][row['month']]
end

看起来 acct.activity 会 return 一个散列。如果您只是执行 acct.activity[year][month],而 acct.activity[year] 为零,那么您将执行 nil[month],这会导致错误。

&&logical and 所以如果 acct.activity[year] 是 nil 那么整个测试将只是 return nil,而不是错误。因此,当您不确定散列中的内容时,这是一种简单的安全机制。

鉴于 acct.activity() returns 嵌套 'hash',它通常用于检查返回的 hash 是否包含预期条目。

a = { :a => {}, :b => { :c => 2 } }

a[:a] && a[:a][:x] ? true : false
# => false
a[:b] && a[:b][:c] ? true : false
# => true