2011-03-09 19 views
3

如果不是從數組中刪除重複的元素,我想刪除具有特定屬性的元素?參數化數組#uniq(即,uniq_by)

具體來說,我想從數組中刪除所有的字符串重複的「本質」,在本質上是這樣定義的:

class String 
    def essence 
    downcase.gsub('&', 'and').gsub(/[^a-z0-9]/, '') 
    end 
end 

我想是這樣的:

['a', 'A', 'b'].uniq_by(&:essence) 
# => ['a', 'b'] (or ['A', 'b']; I don't really care) 

有什麼最好的方法來完成這個?

回答

4

的ActiveSupport有Array#uniq_by,這是代碼:

class Array 
    def uniq_by 
    hash, array = {}, [] 
    each { |i| hash[yield(i)] ||= (array << i) } 
    array 
    end 
end 

刻面也有Enumerable#uniq_by

module Enumerable  
    def uniq_by 
    h = {} 
    inject([]) {|a,x| h[yield(x)] ||= a << x} 
    end  
end 
3

快速和骯髒的方式:

['a', 'A', 'b'].group_by {|i| i.essence}.values.map(&:first) 

和一些猴子補丁:

class Array 
    def uniq_by(&block) 
    group_by(&block).values.map(&:first) 
    end 
end 
+0

嘿,只是想評論說你實際上可以做'group_by(&:essence)',這樣如果你想更新你的答案,你可以! – 2016-04-13 22:06:05

9

由於1.9.2,Array#uniq(和uniq!)取塊,所以對於uniq_by不再需要。

+2

http://ruby-doc.org/core-1.9.2/Array.html#method-i-uniq證實了這一點。 – 2012-03-15 22:06:13

+0

爲了防止其他人遇到這個問題,ruby 1.9.2p180與block的獨特性似乎並不像uniq_by那樣可靠,儘管我還沒有做過大量的測試來弄清楚什麼是問題。 – Kevin 2012-11-12 07:06:49

+0

並可以通過'require'backports''提供給更早的Rubies。 – 2013-02-06 21:39:03