たのしいRuby 第13章 Hashクラス
tanakaは文字列に弱いことが判明してしまった・・・気を取り直して13章のHashに取りかかる。今やHashのない生活なんてありえないので、しっかり学んでいきたい。
ブロックによる初期化
この構文がイマイチ理解出来なかった。
h = Hash.new do |hash, key| hash[key] = key.upcase end h["abc"] = "abc" h["xyz"] p h["abc"] # abc p h["xyz"] # XYZ
色々テストした結果、代入されなかった時に、newの定義が呼ばれることがわかった。
引数にブロック構文を取れるメソッドはイマイチ掴めてない。
単語数のカウント
12章の練習問題の答えがやっと登場・・・。wcの詳細バージョンに改造してみた。単語数と、文字数と行数を詳細に数えます。
count_words.rb
#!/usr/bin/ruby -w def dump_hash(hash) hash.sort { |a,b| b[1] <=> a[1] }.each do |key, value| printf("%s : %s\n", key, "*" * value) end end lines = 0 word_count = Hash.new(0) char_count = Hash.new(0) while line = gets lines += 1 words = line.split words.each do |word| word_count[word] += 1 end chars = line.split(//u) chars.each do |char| char_count[char] += 1 end end printf("==== lines %d\n", lines) puts "==== words" dump_hash(word_count) puts "==== chars" dump_hash(char_count)
実行方法はこんな感じ
% count_words.rb *.rb | less ==== lines 453 ==== words = : ****************************************************************** end : ***************************************************************** p : ****************************************** puts : ************************ ...(略 ==== chars : ***********************....******************* e : ***********************....*************** ...(略
実行結果が長いので、lessを使うといいと思う。
- 単語は=,endの占有率が高い。
- 文字は何故かeの占有率が高い。
改造次第で、案外便利なユーティリティに化けそう。
こんなんつくりてぇ〜。
練習問題
解けるところまで解くぞぉ
ハッシュには配列の%wのようなものがありません。そこで、空白とタブと改行で区切られた文字列をハッシュに変換するstr2hashを定義してください。
p str2hash("blue 青 white 白\nred 赤")
#=> {"white"=>"白", "blue"=>"青", "red"=>"赤"}
僕の答えはこんな感じ。
def str2hash(str) hash = Hash.new array = str.split(/\s+/) until array.empty? key, value = array.slice!(0, 2) hash[key] = value end return hash end p str2hash("blue 青 white 白\nred 赤")
若干、答えと違った。whileの部分。
while key = array.shift value = array.shift hash[key] = value end
僕の方がセクシーだと思う。
最後の問題はむじぃので、飛ばした。
良いblog発見
回答を別のアプローチで解いてて、参考になります。*演算子とか、便利そう。
- Rubyist - バリケンのRuby日記 トップページ
- Rubyist - バリケンのRuby日記 - たのしいruby たのしいrubyで検索かけました。穴が空くまで読ませてもらいます!!