8
@example.each do |e|
  #do something here
end

在这里,我想对每个元素中的第一个和最后一个元素做一些不同的事情,我应该如何实现这一点?当然,我可以使用循环变量 i 并跟踪是否i==0i==@example.size是否太愚蠢?

4

3 回答 3

25

更好的方法之一是:

@example.tap do |head, *body, tail|
  head.do_head_specific_task!
  tail.do_tail_specific_task!
  body.each { |segment| segment.do_body_segment_specific_task! }
end
于 2013-06-16T16:09:52.437 回答
5

您可以使用each_with_index然后使用索引来识别第一个和最后一个项目。例如:

@data.each_with_index do |item, index|
  if index == 0
    # this is the first item
  elsif index == @data.size - 1
    # this is the last item
  else
    # all other items
  end
end

或者,如果您愿意,可以像这样分隔数组的“中间”:

# This is the first item
do_something(@data.first)

@data[1..-2].each do |item|
  # These are the middle items
  do_something_else(item)
end

# This is the last item
do_something(@data.last)

使用这两种方法时,当列表中只有一个或两个项目时,您必须小心期望的行为。

于 2013-06-16T15:48:08.850 回答
2

以下是一种相当常见的方法(当数组中肯定没有重复时)。

@example.each do |e|
  if e == @example.first
    # Things
  elsif e == @example.last
    # Stuff
  end
end

如果您怀疑数组可能包含重复项(或者如果您只是更喜欢这种方法),那么从数组中抓取第一个和最后一个项目,并在块外处理它们。使用此方法时,您还应该将作用于每个实例的代码提取到一个函数中,这样您就不必重复它:

first = @example.shift
last = @example.pop

# @example no longer contains those two items

first.do_the_function
@example.each do |e|
  e.do_the_function
end
last.do_the_function

def do_the_function(item)
  act on item
end
于 2013-06-16T15:48:01.043 回答