Hatena::Grouprubyist

うんたらかんたらRuby RSSフィード

2009-12-12Ruby 練習問題集 ループ処理 (2)

Ruby 練習問題集 ループ処理 (2)

| Ruby 練習問題集 ループ処理 (2) - うんたらかんたらRuby を含むブックマーク はてなブックマーク - Ruby 練習問題集 ループ処理 (2) - うんたらかんたらRuby

ループ処理 (2) - Ruby 練習問題集 - Ruby on Rails with OIAX

今、任意の個数のメールアドレスがあり、ドメイン別にメールアドレスが何個あるかを調べたい。

メールアドレスの配列 ary を引数として取り、ハッシュオブジェクトを返すメソッド foo を作りなさい。

ただし、そのハッシュオブジェクトは以下の条件を満たすこと。

各キーはメールアドレスのドメイン部分(@より後ろの部分)である。

各値は、そのドメイン部分がキーと合致するメールアドレスの個数である。

例えば、次のようなメールアドレスの集合を考える。

john@sample.com

taro@sample.jp

nancy@sample.com

jiro@sample.jp

hermes@oiax.jp

saburo@sample.jp

これらのメールアドレスを要素として持つ配列を作って foo に渡すと、次のようなハッシュオブジェクトが返ることになる。

{

'sample.com' => 2,

'sample.jp' => 3,

'oiax.jp' => 1

}

まぁやってみた

準備

mails=%w(john@sample.com taro@sample.jp nancy@sample.com jiro@sample.jp hermes@oiax.jp saburo@sample.jp)
def foo(ary)
  h = {}
  ary.each do |x|
    domain = x.split("@")[1]
    if h.key?(domain)
      h[domain] += 1
    else
      h[domain] = 1
    end
  end
  h
end

mails=%W(john@sample.com taro@sample.jp nancy@sample.com jiro@sample.jp hermes@oiax.jp saburo@sample.jp)
foo(mails)
=> {"sample.jp"=>3, "oiax.jp"=>1, "sample.com"=>2}

回答を見て納得

ああ、そうか。こういう時こそinjectだった。

||= も正規表現も見やすい。

def foo(ary)
  ary.inject({}) do |hsh, email|
    domain = email.match(/@/).post_match
    hsh[domain] ||= 0
    hsh[domain] += 1
    hsh
  end
end

foo(mails)
=> {"sample.jp"=>3, "oiax.jp"=>1, "sample.com"=>2}
トラックバック - http://rubyist.g.hatena.ne.jp/rochefort/20091212