2012-03-01 15 views
7

actualización: lo siento, me fijo mi programa:cómo comparar con el elemento anterior en el iterador `each`?

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 

¿Hay otra manera hermosa en ruby lenguaje para hacer lo mismo?

por cierto, en realidad. a es un ActiveRecord::Relation en mi caso real.

Gracias.

+1

intenta explicar con palabras la intención, el código parece defectuoso (particularmente que 'x [i-1]' no tiene sentido). La mejor manera: dar algunos ejemplos de entrada y salida esperada. – tokland

+0

gracias, he arreglado mi programa. –

+0

¿Cada eachcons aún era adecuado? –

Respuesta

16

El problema que pueda tener con each_cons es que itera a través de n-1 pares (si la longitud de Enumerable es n). En algunos casos, esto significa que debe manejar las cajas de borde por separado para el primer (o último) elemento.

En ese caso, es muy fácil de implementar un method similar a each_cons, pero que daría (nil, elem0) para el primer elemento (en contraposición a each_cons, que produce (elem0, elem1):

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

puede utilizar 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

Usted puede utilizar 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

Puede utilizar each_cons

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

Como es probable que desee hacer algo más que puts con los duplicados, preferiría mantener los duplicados en una estructura:

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

más en al: https://www.ruby-forum.com/topic/192355 (respuesta genial de David A. Black)

Cuestiones relacionadas