2012-03-07 14 views
6

Say Mam tablicę, która wygląda tak:Jak wykryć zduplikowane wartości w tablicy w Ruby?

a = [cat, dog, cat, mouse, rat, dog, cat] 

Jak to zrobić cykl przez to i zrobić coś z duplikatów - przykład powiedzieć, usunąć?

Innymi słowy, gdybym zrobił a.each do |i|, jak mogę ocenić [0], przeciwko [1], [2], [3] ... a potem, gdy znajdę ten, który chcę, powiedz, że [2] w tym przypadku ma pierwszy duplikat, a następnie popycham go do stosu lub usuwam lub coś takiego.

Wiem, jak oceniać klucze, a nie wartości ... ale jak mogę ocenić wartości względem siebie w obrębie tej samej tablicy?

Dzięki.

Odpowiedz

11

można utworzyć skrót do numeru magazynu razy każdy element jest powtarzany. W ten sposób jednokrotne iterowanie po tablicy.

h = Hash.new(0) 
['a','b','b','c'].each{ |e| h[e] += 1 } 

powinno skutkować

{"a"=>1, "b"=>2, "c"=>1} 
+1

Dlaczego nie 'h = Hash.new (0)' i 'h [e] + = 1'? –

+0

Materia składni. To zależy od programistów. – ch4nd4n

+0

To jest właśnie to, co próbowałem zrobić ... ale ... Nie mogłem wymyślić, jak używać 'nil?' I metod przyrostowych właśnie w ten sposób. Dzięki! – marcamillion

1

Prostym rozwiązaniem jest uruchomienie podwójną pętlę:

a.each_with_index do |a1, idx1| 
    a.each_with_index do |a2, idx2| 
    next if idx1 >= idx2 # Don't compare element to itself 
         # and don't repeat comparisons already made 

    # do something with a pair of elements (a1, a2) 
    end 
end 

Jeśli chcesz po prostu wyeliminować duplikaty, istnieje metoda: Array#uniq.

+0

Pomyślałem o tym, ale wydaje się, że jest tak niechlujnie. Czy istnieje bardziej eleganckie rozwiązanie "ruby-owskie"? – marcamillion

+0

Aby wyeliminować duplikaty, istnieje metoda. Aby porównać wszystkie elementy ze sobą, istnieje podwójna pętla. Osobiście nie widzę w tym bałaganu. Jest to prosty prosty kod, który dobrze się czyta. –

+0

Sergio ta metoda jest nieefektywna, ponieważ dokonujesz niepotrzebnych porównań, które zostały wykonane w przeszłości. Twoja druga wewnętrzna pętla powinna rozpocząć iterację później (tj. Dalej w tablicy) w każdej pętli. – MMM

1

Użyj a.uniq!, aby usunąć duplikaty.

również sprawdzić ruby-doc.org, gdzie można znaleźć więcej informacji na temat metod klasy ruby.

+0

compact usuwa nils z tablicy. Jak to jest pomocne w tej sytuacji? –

+0

Uzgodnione. Patrzyłem na dokumenty i to nie działa. – marcamillion

+0

Przepraszam, że napisałem uniq. :) – lesce

3

Spróbuj tego:

class Array 
    def find_dups 
     uniq.map {|v| (self - [v]).size < (self.size - 1) ? v : nil}.compact 
    end 
end 

a = ['cat', 'dog', 'cat', 'mouse', 'rat', 'dog', 'cat'] 

print a - a.find_dups # Removes duplicates 

find_dups powróci elementy, które mają duplikaty

5

ten działa sprawnie i jest dość prosta:

require 'set' 

visited = Set.new 
array.each do |element| 
    if visited.include?(element) 
    # duplicated item 
    else 
    # first appearance 
    visited << element 
    end 
end 
1

Spróbuj tego:

 
array.inject({}){|h, e| h[e] = h[e].to_i + 1; h} 
0

To będzie drukować wszystkie duplikaty w tablicy :

array.inject(Hash.new(0)) { |hash,val| 
    hash[val] += 1; 
    hash 
}.each_pair { |val,count| 
    puts "#{val} -> #{count}" if count > 1 
} 
0

Jeśli chcesz po prostu pozbyć się duplikatów, najprostszym rozwiązaniem jest wziąć tablicę i zrobić tablicę & tablicę. Użyj operatora &.

Jeśli chcesz wiedzieć, czym są te powtórzenia, po prostu porównaj tablicę do tablicy &.

0

Jeśli tablica jest sortowalna, to coś jak poniżej zwróci tylko duplikaty.

array.sort.each_cons(2).select {|p| p[0] == p[1] }.map &:first 

Sortuje tablicę, a następnie odwzorowuje ją na kolejne pary elementów, wybiera pary, które są takie same, mapy do elementów.

0

Najlepszym sposobem na to jest porównanie go z unikalną wersją samego siebie. Jeśli jest taki sam, to nie ma duplikatów, jeśli nie, duplikaty istnieją.

unique_array = original_array.uniq 

dostać unikalną wersję swojej tablicy

if original_array == unique_array then return true else return false 

porównać go do swojej oryginalnej tablicy.

Proste!

Powiązane problemy