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

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

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

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

Q&A

1回答

1283閲覧

RubyのHashについて

xsugarx

総合スコア8

Ruby

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

1グッド

1クリップ

投稿2016/10/20 09:44

###前提・実現したいこと
RubyでHashを使用してユニークなIDと単語をセットで辞書登録するプログラムを読んでいます。
以下の記述(*)が何をしているのかよくわかりません。
そもそもHashのデータがどのように保持されているのかもよくわかっていません。
本など読みましたが、図などで書いてあるものがなかなか見つけられず想像がついていません。
Hashの仕組みを教えてください。
今回で言う"id = wordId[d[0]]"の箇所は何をidに入れているのですか?
HashのデータはIDと単語の2つを持っているのではないのですか?

また、このプログラムが既出の単語は飛ばしてIDをつけるものだということはわかっているのですが、
どの部分で判断しているのかがわかりません。
初心者ですので基礎知識すら足らないのはわかっていますが、どうぞよろしくお願いいたします。

###ソースコード

Ruby

1def makeDictionary(fileMcb) #単語とIDを辞書登録 2 number = 0 3 wordId = Hash.new #ローカル変数 4 File.open(fileMcb){|fin| 5 fin.each{|line| 6 d = line.chomp.split(/\t/) 7 next if d.size == 1 8 id = wordId[d[0]]() 9 10 if id.nil? 11 wordId[d[0]] = number 12 number +=1 13 end 14 p id 15 } 16 } 17 return wordId 18 end

###試したこと
動作がわからない箇所にpを入れていちいち表示させようとしましたが、(*)の真下に入れてもエラーか何かで表示されませんでした。
eachの外にp idとしたら「nil nil nil nil nil nil 6 nil ...」といった具合に表示されましたが、更に動作がよくわからなくなりました。

###補足情報(言語/FW/ツール等のバージョンなど)
入力ファイルはMecabに通したタブ区切りファイルを想定しています。

DrqYuto👍を押しています

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

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

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

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

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

guest

回答1

0

最初から行きましょうか。。。

def makeDictionary(fileMcb) #単語とIDを辞書登録

fileMcb にはたぶん ファイル名 が入っています

number = 0 wordId = Hash.new #ローカル変数

number0
wordIdHash のインスタンスが入ります。この段階では空っぽで {} ですね。

File.open(fileMcb){|fin|

fileMcb に入っているファイル名のファイルを開きます。開いた結果は fin に入ります

fin.each{|line|

fin (ファイルの内容) を1行づつ読んでいきます。1行読んで line に入れます

d = line.chomp.split(/\t/)

line を分解します。
まず chomp で改行コードを削除し、その後タブ(\t)で分割して配列にします。

a<TAB>b<TAB>c

という行(line)だったら d には ['a', 'b', 'c'] が入ります

next if d.size == 1

もし d.size (さきほどlineを分割した配列dの要素数) が 1 だった場合は next という事で次の行を読みにいきます。その際、ここから下は実行されません。

1 でなかったとして。。。。

id = wordId[d[0]] …(*)

はい。問題の箇所ですね
d[0] は配列の0番目(最初)の要素です。
さきほどの例ですと 'a' ですね。

という事は

id = wordId['a'] …(*)

と一緒です。
Hash である wordIdkey'a'valueid に代入するという事になります。
今1行目ですので wordId は空 {} でしたという事は wordId['a']nil になり、それが id に代入されます。

if id.nil?

もし idnil だったら。。。

wordId[d[0]] = number

d[0]'a' でした。なので同じく wordId['a']number を代入です。
numberは一番最初に0にしてましたね。
という事は wordId['a'] == 0 です。

number +=1

これは number = number + 1 の別の書き方なので number1 になります

end

もし idnil だった時の処理おしまい。

p id

id を表示

}

これは fin.each{|line| の閉じかっこですので、そこに戻って次の行が読み込まれ同じように処理されます。

最後の行だった場合は下へ

}

これは ** File.open(fileMcb){|fin|** の閉じかっこですのでファイルを閉じます。

return wordId

呼び出し元に wordId という Hash を返して

end

おしまし。ちゃんちゃん。

投稿2016/10/20 10:05

hana-da

総合スコア1728

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問