2016-06-13 64 views
2

我有一個電子郵件地址陣列(大概超過50,000個),我有興趣計算特定電子郵件域的頻率。舉例來說,如果我有用分隔符分隔電子郵件字符串

emails = [ 
    '[email protected]', 
    '[email protected]', 
    '[email protected]', 
    '[email protected]', 
    '[email protected]' 
] 

,我很感興趣,其中電子郵件域出現最多的,我希望與頻率2返回'gmail'

要做到這一點,我認爲這是一個好主意,通過數組並丟棄在@之前發生的所有事情,並將域保存爲新數組,然後我可以迭代。我將如何做到這一點?

回答

5

假設你的電子郵件是string,你可以做這樣的事情:

emails = ["[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]"] 
counts = Hash.new(0) 
emails.each { |t| counts[t.partition("@").last] += 1} 
counts #{"gmail.com"=>2, "yahoo.com"=>1, "aol.com"=>1, "someuni.xyz.com"=>1} 
+2

您可以將它組合到'counts = emails.each_with_object(Hash.new(0)){| t,h | ...}' – Stefan

+0

謝謝!如果我然後想根據整數來排序信息,我該怎麼做?例如,如果我使用'counts.sort'(取自您使用的相同計數),我會得到一個輸出,如[gmail.com,2],[yahoo.com,1] ..'這將按字母順序排列。我想用數字順序排序,換句話說,用頻率最高的電子郵件排序 – Chumbawoo

+0

不要緊,它似乎使用'counts.sort_by {| a,b | b.to_i}' – Chumbawoo

2
emails.map { |e| e.split('@').last } # leave domains 
     .group_by { |s| s }   # group 
     .map { |k, v| [k, v.count] } # count 
     .sort_by(&:last)    # sort 
     .last       # get results 
#⇒ ["gmail.com", 2] 
+2

有趣的是,提供預期結果的唯一答案(「我想返回頻率爲2的'gmail')被downvoted :) – mudasobwa

2

我認爲這將是一個好主意,[...]只保留域作爲新數組,然後我可以迭代。我將如何做到這一點?

您應該使用合適的庫來解析電子郵件地址,例如Mail寶石。它配備了一個實用工具類Mail::Address提供對地址字段輕鬆訪問:

require 'mail' 

emails = %w[ 
    [email protected] 
    [email protected] 
    [email protected] 
    [email protected] 
    [email protected] 
] 

domains = emails.map { |email| Mail::Address.new(email).domain } 
#=> ["gmail.com", "yahoo.com", "aol.com", "someuni.xyz.com", "gmail.com"] 

它也可以處理更爲複雜的地址格式。來自documentation

a = Address.new('Mikel Lindsaar (My email address) <[email protected]>') 
a.format  #=> 'Mikel Lindsaar <[email protected]> (My email address)' 
a.address  #=> '[email protected]' 
a.display_name #=> 'Mikel Lindsaar' 
a.local  #=> 'mikel' 
a.domain  #=> 'test.lindsaar.net' 
a.comments  #=> ['My email address'] 
a.to_s   #=> 'Mikel Lindsaar <[email protected]> (My email address)' 
3

類似於mudasobwa的回答。

emails 
.group_by{|s| s.partition("@").last} 
.map{|k, v| [k, v.length]} 
.max_by(&:last) 
# => ["gmail.com", 2]