2012-03-07 113 views
6

說我有一個數組,看起來像:如何在Ruby中檢測數組中的重複值?

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

如何通過做我循環,並做一些重複 - 例如說刪除它們?

換句話說,如果我做了a.each do |i|,我該如何評估[0],針對[1],a [2],a [3] ...然後當我找到我想要的那個時,在這種情況下說一個[2]有第一個重複,然後我把它推到堆棧或刪除它或某物。

我知道如何評估鍵,值與值...但我如何評估相同數組內的對方值?

謝謝。

回答

11

您可以創建一個哈希的時間的任何元素重複門店數量的元素。因此只需要在數組上迭代一次。

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

應該導致

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

爲什麼不'h = Hash.new(0)'和'h [e] + = 1'? – 2012-03-07 13:18:32

+0

語法問題。這是程序員的自由裁量權。 – ch4nd4n 2012-03-07 14:05:11

+0

這實際上是我想要做的......但是......我無法弄清楚如何使用'nil?'並像這樣增加方法。謝謝! – marcamillion 2012-03-07 20:37:03

1

一個簡單的解決方案是運行一個雙循環:

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 

如果你只是想消除重複,有一個方法:Array#uniq

+0

想到這個,但它似乎很混亂。還有更優雅的'ruby-ish'解決方案嗎? – marcamillion 2012-03-07 10:39:48

+0

爲了消除重複,有一種方法。爲了比較所有元素彼此,有一個雙循環。我個人沒有看到任何混亂。這是簡單的簡單的代碼,讀得很好。 – 2012-03-07 10:44:09

+0

塞爾吉奧這種方法效率低下,因爲你正在進行過去不必要的比較。你的第二個內循環應該在每個循環的後面開始迭代(即進一步在數組中)。 – MMM 2012-03-07 10:48:08

1

使用 a.uniq!刪除重複項。

也可以結算ruby-doc.org在這裏你可以找到更多關於ruby的類方法的信息。

+0

compact從陣列中刪除nils。在這種情況下它有什麼用處? – 2012-03-07 10:37:26

+0

同意。看着文檔,它不起作用。 – marcamillion 2012-03-07 10:39:01

+0

對不起,我寫了uniq。 :) – lesce 2012-03-07 10:39:19

3

試試這個:

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將返回有重複

5

這有效運作,是相當簡單:

require 'set' 

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

試試這個:

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

這將打印所有副本中的數組:

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

如果你只是想擺脫重複,最簡單的事情是採取陣列和做數組&數組。使用&運算符。

如果你想知道那些重複是什麼,只需比較陣列&數組。

0

如果數組是可排序的,則類似下面的內容將僅返回重複項。

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

排序陣列,然後將其映射到連續的雙元件,選擇對它們是相同的,映射到的元素。

0

做到這一點的最好方法是將其與自身的獨特版本進行比較。如果它相同,那麼它沒有重複,如果不是,則存在重複。

unique_array = original_array.uniq 

得到您的陣列的唯一版本

if original_array == unique_array then return true else return false 

把它比原來的數組。

簡單!