在嵌套循环中Ruby优雅替代++?

时间:2015-05-26 21:31:31

标签: ruby loops syntax counter

在此之前,我已阅读Why doesn't Ruby support i++ or i—?所有答案并理解原因。请注意这不仅仅是关于是否拥有它的另一个讨论主题

我真正追求的是一个更优雅的解决方案,让我对Ruby中的++ / --感到疑惑和研究。我已经查找了循环,eacheach_with_index等等,但我无法找到更好的解决方案适用于此特定情况

少说话,更多代码:

# Does the first request to Zendesk API, fetching *first page* of results
all_tickets = zd_client.tickets.incremental_export(1384974614)

# Initialises counter variable (please don't kill me for this, still learning! :D )
counter = 1

# Loops result pages
loop do

  # Loops each ticket on the paged result
  all_tickets.all do |ticket, page_number|
    # For debug purposes only, I want to see an incremental by each ticket
    p "#{counter} P#{page_number} #{ticket.id} - #{ticket.created_at} | #{ticket.subject}"
    counter += 1
  end

  # Fetches next page, if any
  all_tickets.next unless all_tickets.last_page?

  # Breaks outer loop if last_page?
  break if all_tickets.last_page?

end

目前,我需要counter仅用于调试目的 - 它根本不是什么大不了的事 - 但我的好奇心本身就输出了这个问题:是否有更好的(更美观,更优雅)的解决方案为了这?只有counter += 1的整行似乎相当沉闷。仅作为示例,在打印字符串时使用"#{counter++}"会更简单(至少为了可读性)。

我不能简单地使用.each索引,因为它是一个嵌套循环,它会在每个页面重置(外循环)。

有什么想法吗?

BTW:这个问题与Zendesk API无关,没有。我只是用它来更好地说明我的情况。

4 个答案:

答案 0 :(得分:1)

对我而言,counter += 1是表达递增计数器的好方法。

你可以在0开始你的计数器,然后写下你想要的效果:

p "#{counter += 1} ..."

但我一般不会推荐这个,因为人们不会期望在字符串插值中更改变量等副作用。

如果您正在寻找更优雅的东西,那么每次在枚举器上调用next时,您应该设置一个Enumerator,一次返回一个整数。

nums = Enumerator.new do |y|
  c = 0
  y << (c += 1) while true
end

nums.next  # => 1
nums.next  # => 2
nums.next  # => 3

您可以写下:

,而不是在上面的代码中使用Enumerator.new
nums = 1.upto(Float::INFINITY)

答案 1 :(得分:0)

all_tickets.each_with_index(1) do |ticket, i|

我不确定page_number来自哪里......

请参阅Ruby Docs

答案 2 :(得分:0)

正如B Seven所提到的,each_with_index会起作用,但你可以保留page_number,因为all_tickets是元组的容器,因为它必须立即正在工作。

all_tickets.each_with_index do |ticket, page_number, i|
   #stuff
end

其中 i 是索引。如果你在all_tickets的每个元素中都有多个ticket和page_number,你继续放置它们,只要记住索引是额外的索引并且应该保留在最后。

答案 3 :(得分:0)

我可能会过度简化您的示例,但您可以像这样从内部和外部范围计算出一个计数器。

all_tickets = *(1..10)
inner_limit = all_tickets.size
outer_limit = 5000
1.upto(outer_limit) do |outer_counter|
  all_tickets.each_with_index do |ticket, inner_counter|
    p [(outer_counter*inner_limit)+inner_counter, outer_counter, inner_counter, ticket]
  end
  # some conditional to break out, in your case the last_page? method
  break if outer_counter > 3
end