2013-06-16 16 views
8
@example.each do |e| 
    #do something here 
end 

ここでは、それぞれの最初と最後の要素とは異なる何かをしたいのですが、これをどのように達成する必要がありますか?確かに私はループ変数iを使用して、i==0または[email protected]の場合は追跡しますが、あまりにも愚かではありませんか?それぞれの最初と最後の要素を区別する?

答えて

24

よりよいアプローチの一つは、次のとおりです。

@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 
+4

ああ、それはちょうど_awesome_です。 –

+1

これは本質的に@thomasfedb's答えの第2部と同じです(http://stackoverflow.com/a/17135002/410102) – akonsu

+0

+1ですが、なぜか 'head、* body、tail = @ example' ? – steenslag

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 
+0

'@のexample'が重複して含まれている場合、これは壊れます。 – thomasfedb

+0

@Mattさんの回答をお寄せいただきありがとうございます。 – thomasfedb

+0

コメントありがとう:)通常、この種の動作はデータベースコレクションをターゲットにしているので、通常は重複はありませんが、OPは私が確かにそれを想定してはならないと述べていないためです。 – Matt

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) 

をリスト内の1つまたは2つの項目のみです。

関連する問題