2013-06-16 11 views

risposta

24

Uno degli approcci più bello è:

@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

Oh wow, questo è solo _awesome_. –

+1

questo è essenzialmente la seconda parte della risposta di @ thomasfedb (http://stackoverflow.com/a/17135002/410102) – akonsu

+0

+1, ma perché non solo "head, * body, tail = @ example" ? – steenslag

2

Un approccio abbastanza comune è il seguente (quando non ci sono certamente duplicati nell'array).

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

Se gamma sospetta possa contenere duplicati (o per chi preferisce questo metodo) poi afferrare i primi e gli ultimi elementi fuori della matrice, e gestirli al di fuori del blocco. Quando si utilizza questo metodo si dovrebbe anche estrarre il codice che agisce su ogni istanza a una funzione in modo che non c'è bisogno di ripeterlo:

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

Questo si romperà se '@ example' contiene duplicati. – thomasfedb

+0

Grazie per aver aggiornato la tua risposta @Matt. – thomasfedb

+0

Grazie per il commento :) Spesso nelle rotaie questo tipo di comportamento è mirato ad una raccolta di database, quindi normalmente i duplicati sono improbabili, ma dal momento che OP non afferma che certamente non avrei dovuto assumerlo. – Matt

5

È possibile utilizzare each_with_index e quindi utilizzare l'indice per identificare il primo e ultimi oggetti. Per esempio:

@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 

In alternativa, se si preferisce si potrebbe separare il 'mezzo' della matrice in questo modo:

# 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) 

Con entrambi questi metodi bisogna stare attenti al comportamento desiderato quando c'è sono solo uno o due elementi nella lista.

Problemi correlati