2012-03-01 4 views
7

aggiornamento: mi dispiace, ho fissato il mio programma:come confrontare con l'elemento precedente in `ciascun` iteratore?

a = [ 'str1' , 'str2', 'str2', 'str3' ] 
name = '' 
a.each_with_index do |x, i | 
    if x == name 
    puts "#{x} found duplicate." 
    else 
    puts x 
    name = x if i!= 0 
    end 
end 



    output: 
str1 
str2 
str2 found duplicate. 
str3 

C'è un altro bel modo di ruby linguaggio per fare la stessa cosa?

btw, in realtà. a è un ActiveRecord::Relation nel mio caso reale.

Grazie.

+1

prova a spiegare con le parole l'intento, il codice sembra bacato (in particolare che 'x [i-1]' non ha senso). Il modo migliore: dare alcuni esempi di input e output attesi. – tokland

+0

grazie, ho risolto il mio programma. –

+0

Ogni_cons è ancora adatto? –

risposta

16

Il problema si potrebbe avere con each_cons è che itera attraverso n-1 coppie (se la lunghezza dell'Enumerable è n). In alcuni casi questo significa che devi gestire separatamente i casi limite per il primo (o ultimo) elemento.

In questo caso, è davvero facile da implementare un method simile a each_cons, ma che produrrebbe (nil, elem0) per il primo elemento (al contrario di each_cons, che produce (elem0, elem1):

module Enumerable 
    def each_with_previous 
    self.inject(nil){|prev, curr| yield prev, curr; curr} 
    self 
    end 
end 
12

è possibile utilizzare each_cons:

irb(main):014:0> [1,2,3,4,5].each_cons(2) {|a,b| p "#{a} = #{b}"} 
"1 = 2" 
"2 = 3" 
"3 = 4" 
"4 = 5" 
3

Si può usare Enumerable#each_cons:

a = [ 'str1' , 'str2', 'str3' , ..... ] 
name = '' 
a.each_cons(2) do |x, y| 
    if y == name 
    puts 'got you! ' 
    else 
    name = x 
    end 
end 
5

È possibile utilizzare each_cons

a.each_cons(2) do |first,last| 
    if last == name 
    puts 'got you!' 
    else 
    name = first 
    end 
end 
1

Come probabilmente si desidera fare di più che puts con i duplicati, avrei preferito tenere i duplicati in una struttura:

### question's example: 
a = [ 'str1' , 'str2', 'str2', 'str3' ] 
# => ["str1", "str2", "str2", "str3"] 
a.each_cons(2).select{|a, b| a == b }.map{|m| m.first} 
# => ["str2"] 
### a more complex example: 
d = [1, 2, 3, 3, 4, 5, 4, 6, 6] 
# => [1, 2, 3, 3, 4, 5, 4, 6, 6] 
d.each_cons(2).select{|a, b| a == b }.map{|m| m.first} 
# => [3, 6] 

maggiori info su a: 0.123.669,961708 millions(bella risposta di David A. Black)