2012-03-01 4 views
7

aktualizacja: Przepraszam, ale stały mój program:jak porównać do poprzedniego elementu w "każdym" iteratorze?

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 

Czy istnieje inny sposób na piękny ruby języku zrobić to samo?

btw, faktycznie. a to ActiveRecord::Relation w moim prawdziwym przypadku.

Dzięki.

+1

spróbuj wyjaśnić słowami intencję, kod wydaje się błędny (szczególnie, że 'x [i-1]' nie ma sensu). Najlepszy sposób: podaj przykłady danych wejściowych i oczekiwanych wyników. – tokland

+0

dzięki, naprawiłem program. –

+0

Czy nadal były odpowiednie? –

Odpowiedz

16

problem może mieć z each_cons jest to, że iteracje przez n-1 par (jeśli długość liczby zmiennej to n). W niektórych przypadkach oznacza to, że musisz osobno obsługiwać przypadki krawędzi dla pierwszego (lub ostatniego) elementu.

W tym przypadku, jest to bardzo proste do wdrożenia method podobny do each_cons, ale które przyniosą (nil, elem0) dla pierwszego elementu (w przeciwieństwie do each_cons, co daje (elem0, elem1):

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

można użyć 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

Można użyć 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

Można użyć each_cons

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

Jak zapewne chcą zrobić więcej niż puts z duplikatów, wolałbym zachować duplikaty w strukturze:

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

więcej na stronie: https://www.ruby-forum.com/topic/192355 (fajna odpowiedź Davida A. Black)