代码之家  ›  专栏  ›  技术社区  ›  Peter

在Ruby循环中第一次做一些特别的事情

  •  1
  • Peter  · 技术社区  · 16 年前

    假设我有一个这样的循环:

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

    鲁比有写东西的方法吗 if FIRST_TIME_AROUND ?我隐约记得读过一次关于这个的文章,但我记不起来了。

    编辑:我知道很多标准的方法…我在寻找最优雅的解决方案。

    8 回复  |  直到 10 年前
        1
  •  11
  •   ykaganovich Mike Samuel    16 年前
    items.each_with_index do |x, i|
      do_something if i==0
      do_rest
    end
    
        2
  •  5
  •   glenn mcdonald    14 年前
    do_something
    items.drop(1).each do |x|
      do_rest
    end
    
        3
  •  2
  •   Greg    16 年前

    如果可能的话,最优雅的方法就是在循环之外做一次性的事情。

        4
  •  0
  •   ykaganovich Mike Samuel    16 年前

    有一种丑陋的、通用的方法,不是针对Ruby的:

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

    这种逻辑丑陋、冗长,但在大多数语言中都有效。

        5
  •  0
  •   Mongus Pong    16 年前

    我创建了一个小的实用程序扩展来处理这种情况。扩展有点难看,但它确实可以使其他地方的代码更整洁。

    它允许您编写如下代码:

        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
    
        6
  •  0
  •   Jakub Hampl    14 年前
    do_something items.first
    items.each do |item|
      do_something_else item
    end
    
        7
  •  0
  •   chech    13 年前

    我的建议是:

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

    原因:

    • 放置 如果 循环内部是未优化的。
    • 我相信这是对执行时间和内存使用最优化的答案。
        8
  •  0
  •   Abram    10 年前

    下面是如何在视图中围绕某些元素生成一个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>
    
    推荐文章