質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

3回答

1336閲覧

each文の中で、hashにキーと値を追加したい。 言語ruby

kanjin555

総合スコア7

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2018/03/20 05:23

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

each文の中で、hashにキーと値を追加していきたいが、each文が実行される度に、追加ではなく、更新されてしまう。

該当のソースコード

def express_addresses(address)

domains = {}
addresses = address.group_by {|domain| domain.split("@")[1]}

addresses.each do |address|
domains = {address[0] => address[1].size}
end
puts domains
end

address = [
"asia@gmail.com", "japan@gmail.com" , "asia@yahoo.jp" , "india@ezweb.ne.jp" , "korea@yahoo.jp" ,
"china@gmail.com" , "mongol@softbank.ne.jp" ,
]

express_addresses(address)

ruby ソースコード

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

{"gmail.com"=>3, "yahoo.jp"=>2, "ezweb.ne.jp"=>1, "softbank.ne.jp"=>1}
上記のように出力させたいのですが、
{"softbank.ne.jp"=>1}
この文しか出力されません。
each文の中で、 domainsというハッシュにキーと値を追加するように書いているつもりなのですが、実際には更新されているみたいです。
大変初歩的な質問ではありますが、お答えしていただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

each文の中で、 domainsというハッシュにキーと値を追加するように書いているつもりなのですが

実際のコードはそうなっておらず、毎回ゼロからハッシュを作成する形になっているので、最後のしか残りません。値1つで代入しましょう。

ruby

1addresses.each do |address| 2 domains[address[0]] = address[1].size 3end

投稿2018/03/20 05:29

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kanjin555

2018/03/26 02:04

ご回答ありがとうございました。 修正した所、キーと値を追加する事ができました。
guest

0

いろいろな修正方法を考えてみました。

ruby

1def express_addresses(address_array) 2 addresses = address_array.group_by { |domain| domain.split('@')[1] } 3 4 # 質問文の方法 5 domains = {} 6 addresses.each do |address| 7 domains = { address[0] => address[1].size } 8 end 9 puts domains 10 puts 11 12 # 修正 1 13 domains = {} 14 addresses.each do |address| 15 domains[address[0]] = address[1].size 16 end 17 puts domains 18 puts 19 20 # 修正 2 (key.val で受ける)  21 # [0[, [1] より、key, val のほうが意味が明確になる 22 domains = {} 23 addresses.each { |(key, val)| domains[key] = val.size } 24 puts domains 25 puts 26 27 # 修正 3 (inject を使う) 28 # domains = {} の初期化が不要になる 29 domains = addresses.inject({}) do |memo, (key, val)| 30 memo[key] = val.size 31 memo 32 end 33 puts domains 34 puts 35 36 # 修正 4 (each_with_object を使う) 37 # ブロックに最後の memo が不要になる 38 puts addresses.each_with_object({}) { |(key, val), memo| memo[key] = val.size } 39 puts 40 41 # 修正 5 (map を使う) 42 puts addresses.map { |k, v| [k, v.size] }.to_h 43end 44 45address = [ 46 'asia@gmail.com', 'japan@gmail.com', 'asia@yahoo.jp', 47 'india@ezweb.ne.jp', 'korea@yahoo.jp', 'china@gmail.com', 48 'mongol@softbank.ne.jp' 49] 50 51express_addresses(address)

実行結果
イメージ説明

inject, each_with_object, map については、API リファレンスなどを google で検索して読むことをお勧めします。

投稿2018/03/21 01:19

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kanjin555

2018/03/26 02:03

教えてくださりありがとうございました。 試した所、値を追加する事ができました!
guest

0

domains = {address[0] => address[1].size}

の一行で、ペア一個のハッシュに上書きしています。

二行目で宣言した空のハッシュに追加したいなら、以下のような感じです。

domains[address[0]] = address[1].size

投稿2018/03/20 05:31

kazto

総合スコア7196

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazto

2018/03/20 05:33

タッチの差で出遅れました・・・
kanjin555

2018/03/26 02:04

ご回答ありがとうございました。 上書きではなく、追加できるようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問