2009-10-08 14 views
1

比方說,我有這樣一個循環:周圍做一些特別的第一次在Ruby環

items.each do |x| 
    if FIRST_TIME_AROUND 
    # do something 
    end 
    # do the rest of stuff 
end 

有在Ruby的方式來寫if FIRST_TIME_AROUND?我隱約記得曾經閱讀過這方面的內容,但我不記得。

編輯:我知道(許多)這樣做的標準方法......我追求最優雅的解決方案。

回答

11
items.each_with_index do |x, i| 
    do_something if i==0 
    do_rest 
end 
+0

你就可以拋棄我作爲第二個變量,它是從0開始的循環中的當前數字。我通常將其稱爲int,但我工作得很好。 – 2009-10-08 02:30:41

0

有一個醜陋的,通用的方式,而不是具體到Ruby:

first = true 
items.each do |x| 
    if first 
    first = false 
    # do something 
    end 
    # do the rest of stuff 
end 

那種邏輯是醜陋的,冗長,但在大多數語言的作品。

2

最優雅的方法就是儘可能在循環外做一次性的事情。

0

我創建了一個小實用程序擴展來處理這種情況。該擴展有點難看,但它確實使其他地方的代碼更加整潔。

它可以讓你寫的代碼,如:

nodes.each_position do |position| 
     position.first do |first_node| 
      # Do stuff on just the first node 
     end 
     position.all do |node| 
      # Do stuff on all the nodes 
     end 
     position.last do |last_node| 
      # Do some extra stuff on the last node 
     end 
     end 

添加這個地方:

# 
# Extends enumerable to give us a function each_index 
# This returns an Index class which will test if we are the first or last 
# or so item in the list 
# Allows us to perform operations on only selected positions of an enumerable. 
# 
module Enumerable 

    class Index 
    attr_accessor :index 
    attr_accessor :object 
    def initialize(count) 
     @index = 0 
     @count = count 
     @object = nil 
    end 

    def first 
     if @index == 0 
     yield(@object) 
     end 
    end 

    def not_first 
     if @index != 0 
     yield(@object) 
     end 
    end 

    def last 
     if @index == @count - 1 
     yield(@object) 
     end 
    end 

    def not_last 
     if @index != @count - 1 
     yield(@object) 
     end 
    end 

    def all 
     yield(@object) 
    end 

    def index(idx) 
     if @index == idx 
     yield(@object) 
     end 
    end 
    end 

    # Add the method to enumerables. 
    # Iterates through the list. For each element it creates an Index instance 
    # and passes it the index of the iteration, the length of our list and the 
    # object at the index. 
    # 
    def each_position 
    count = 0 
    index = Index.new(self.length) 

    self.each do |obj| 
     index.index = count 
     index.object = obj 
     yield index 
     count += 1 
    end 

    end 
end 
0
do_something items.first 
items.each do |item| 
    do_something_else item 
end 
5
do_something 
items.drop(1).each do |x| 
    do_rest 
end 
0

我的建議:

items.first # do something 

items[1..items.count-1].each do |item| 
    do_whatever 
end 

原因:

  • 把一個如果一個循環內是沒有優化。
  • 我相信這是對執行時間和內存使用最優化的答案。
0

下面是如何做到這一點的看法生產周圍的一些元素一個div一個例子:

<% @provider.organizations.each_with_index do |organization, i| %> 
    <% if i == 0 %> 
    <div> 
    <% end %> 
    <span class="label label-warning"><%= organization.name %></span> 
    <% if i == @provider.organizations.count - 1 %> 
    </div> 
    <% end %> 
<% end %> 

輸出:

<div> 
    <span class="label label-warning">AAA</span> 
    <span class="label label-warning">ADA</span> 
    <span class="label label-warning">ABA</span> 
</div> 
相關問題