たのしいRuby 第11章 Arrayクラス
Rubyのイテレーターを理解するためにはArrayクラスをマスターするのが手っ取り早い。
今日はArrayクラスからのスタートです。今日もバリバリ書くぞぉ〜
っと、その前に・・・
いやなブログ - スクリプト言語用のデバッガの使い方 - Ruby, Python, Perlを見ながら、簡単なRubyとPerlのデバッガの使い方を覚えた。
使い方は大体gdbと一緒。ポイントはrが無いこと。hでヘルプが見れる。
pデバッグの方が簡単かもしれないが、規模がでかくなってきたら活用したほうがいいと思う。
詳しい使い方はそれぞれ、プログラミングRuby言語蝙、ラクダ本に書いてある。
言語蝙を持っていないので、購入検討中〜。
も必見。
配列の作り方
連番の配列を作りたいときは、
irb(main):012:0> ("a".."d").to_a => ["a", "b", "c", "d"] irb(main):013:0> (1..10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Rangeクラスを使う手がある。
irb(main):017:0> Array.new(5, "foo") => ["foo", "foo", "foo", "foo", "foo"]
初期化も便利。
irbで漢字コード指定
pの時、文字コードが出てしまうとデバッグしにくいので、-Kuを付けて起動してみた。
% irb -Ku irb(main):001:0> p %w{ゆうてい みやおう きむこう ほりいゆうじ とりやまあきら} ["ゆうてい", "みやおう", "きむこう", "ほりいゆうじ", "とりやまあきら"] => nil
irbでもいけた。化けてな〜い。
split
激しくよく使うのでしっかりやっておく。/etc/passwdの分解。
irb(main):016:0> open("/etc/passwd").each do |lines| irb(main):017:1* p lines.split(":") irb(main):018:1> end ["root", "x", "0", "0", "root", "/root", "/bin/bash\n"] ["bin", "x", "1", "1", "bin", "/bin", "/sbin/nologin\n"] ["daemon", "x", "2", "2", "daemon", "/sbin", "/sbin/nologin\n"]
インデックスの使い方
Rubyの配列はすげぇ
irb(main):041:0> a = ("a".."d").to_a => ["a", "b", "c", "d"] irb(main):042:0> a[1, 3] => ["b", "c", "d"] irb(main):043:0> a[1..3] => ["b", "c", "d"] irb(main):044:0> a[1, 0] = ["X", "Y"] => ["X", "Y"] irb(main):045:0> p a ["a", "X", "Y", "b", "c", "d"] => nil
柔軟すぎる。
集合
集合も扱える
irb(main):054:0> a = ("a".."c").to_a => ["a", "b", "c"] irb(main):055:0> b = ("b".."d").to_a => ["b", "c", "d"] irb(main):056:0> a & b => ["b", "c"] irb(main):057:0> a | b => ["a", "b", "c", "d"] irb(main):058:0> a - b => ["a"] irb(main):059:0> a + b => ["a", "b", "c", "b", "c", "d"]
ありえない。
Rubyは数学に強いらしい。
休憩〜
休憩中に、「るびま」の初回号を読む。
半分くらい話がわからん。もう一度読み返したい。
lispとSmalltalkを学んだ方がいい。が・・・viper的にlispを使う機会が無い・・・来年あたりに・・・emacsとlispを学ぶかなぁ・・・。
GWはとことんRubyでいくぞぉぉぉぉぉ!!!!!!!!
破壊的メソッド
破壊的メソッドについてイマイチ理解できなかったけど、下のコードで理解できた。
irb(main):114:0> a = (1..10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] irb(main):115:0> a.reject { |i| i > 2 } => [1, 2] irb(main):116:0> a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] irb(main):117:0> a.reject! { |i| i > 2 } => [1, 2] irb(main):118:0> a => [1, 2]
- !が付いたら、aそのものを変更する。
- !が付かなかったら,aを変更しない。
unshift,shift,pop,pushは!が付かなくても破壊的。
いろんなメソッド
配列系を全部試した。collect,zip,sort等かなり配列メソッドが充実している。使いこなせるのか疑問詞・・・。
練習問題
最後の問題が激ムズ!!
"括弧が正しく整列しているか判別せよ。"
しかも、"(", ")", "{", "}"混じりで。
ムズすぎなので、"(",")"のみにした。
p balanced?(%w"( ( ( ) ( ) ( ) ( ) ) )") # true p balanced?(%w"( ( ) ) ( ) ( ) ( ) ) )") # false
悩んだ末、こんな感じになった。
#!/usr/bin/ruby def balanced?(a) s = [] a.each_with_index do |b, i| # p s case b when "(" s.push(b) when ")" if s.last == "(" s.pop else return false end else return false end if s.size == 0 && i != a.length - 1 return false end end return true end p balanced?(%w"( ( ( ) ( ) ( ) ( ) ) )") p balanced?(%w"( ( ) ) ( ) ( ) ( ) ) )")
セクシーじゃないけど、なんとかツリーを辿ることが出来た。特に最後がダメ杉。
これから答合わせしま〜す。
練習問題の修正
書き直した。やはり、答えの方が断然セクシー
#!/usr/bin/ruby def balanced?(a) s = [] a.each do |b| case b when "(","{" s.push(b) when ")" c = s.pop if c != "(" return false end when "}" c = s.pop if c != "{" return false end else return false end end if s.empty? return true else return false end end p balanced?([]) #=> true p balanced?(["(",")"]) #=> true p balanced?(["{","(",")","}"]) #=> true p balanced?(["{","(",")"]) #=> false p balanced?(["(",")","}"]) #=> false p balanced?(["(", "{", "{", "}", "(", ")", "}", "(", ")", ")"]) #=> true p balanced?(["(", "{", "{", "}", "(", "}", ")", ")"]) #=> false
最後の位置がマズかった。テスト項目も足りなすぎる。
popもすっきりしたし、eachでいけるようになった。
練習問題をやってみると、自分の基礎の足りなさに気づかされる。アルゴリズムも勉強しないとなぁ・・・。