30代でジョブチェンジ

30代中盤、社会人経験約10年の男性です。転職をしてすぐに退職勧奨を受けて無職をしながらIT関連の学習をしていました。現在は業界で就労中です。

楽しいRuby 第4版 Stringクラス

楽しいRubyで残しときたいメモが以外に多いので分ける。
わかったことと練習問題の回答を記す。
練習問題はできる限り自信の回答を記すが、うまく行かない場合、
回答を貼ることもあります。ネタバレ注意

文字列を作る

ヒアドキュメント

改行を含む長い文字列を作る時に便利 「<<」 これ

10.times do |i|
 10.times do |j|
  print(<<"EOB")
    i : #{i}
    j : #{j}
EOB 
end
end

EOBという文字列までが1つの文字列であることを示す。行頭に終了文字を置く必要があるが、<<-"EOB" とすることで、終了文字列のインデントを気にしなくてよくなる。

コマンドの結果を受け取り文字列にする

コマンドの標準出力を受け取って文字列オブジェクトにする。
`コマンド`で受け取れる

printfメソッドの使い方

printfは決められたフォーマットで文字列を出力するためのメソッド

n = 123
1 printf ("%d\n", n) #=> 123
2 printf ("%4d\n" n) #=> _123
3 printf ("%04d\n" n) # => 0123
4 printf ("%+d\n" n) # => +123

最初の引数がどのようなフォーマットで出力するかの指定になる。
2つ目以降の引数がフォーマット内の%に埋め込まれる。
2行目は4桁表示されるので、先頭が空白になり出力される。
3行目は4桁表示されるが、先頭が0になるという指定。
4行目は桁数の指定はないが、出力する際に+をつけるというものになる。文字列についても同様のことができる。%sを使って認識させる。

sprintfとは

printfは出力だが、sprintfはprintfと同様の結果を文字列オブジェクトとして生成するメソッド

sprintf ("%d\n", 123) #=> "123"
sprintf ("%04d\n", 123) #=> "0123"

printfは出力、sprintfはオブジェクト生成をすると理解した。

練習問題

文字列の各単語を要素とする配列を作成する

.split(" ")を使って文字列を配列に変更した。

作った文字列に含まれる文字とその文字数を次の形式で出力させる
' ': ******
'R': *
'a': ****

これが一番わからなかった。出力する文字列は全てなのか、それとも重複を避けるのかもわからなかった。とりあえず最初に思いついた回答

a = "Ruby is an object oriented programming language"

a.each_char do |s|
    v = "*" * a.count(s) 
    puts "'#{s}': #{v}"
end

こうすると出力結果は全部の文字列に対して、アスタリスクの数を記してしまう。例えばaという文字は4回出てくるが、aが出てくるたびに、'a' : ****を出力してしまう。まずはaの文字列を重複しないようにするのが先なのか。

回答がこんな感じ

str = "Ruby is an object oriented programming language"
cousnt = Hash.new
str.each_char do |c|
  unless count[c] 
  count[c] = 0 
  end
  count[c] += 1
end

表示のさせ方は割愛ですが、これハッシュを使っている。
1文字づつ取り出したものをハッシュに直していく。ハッシュのキーが偽ならば、要素を0にして新たなキーを作る。作ったキーに対しては、絶対に1をカウントすることで1文字からカウントできる。思いつかなかった。
これで重複しない1文字に対する文字数が出てきたので、残るはこれをソートして、printfで表示の仕方を整える。

count.keys.sort.each do |c|
 printf("'%s': %s\n", c, "*" * count[c])
 end

第一引数でスタイルを、第二引数は第一引数の左側、第三引数は第一引数の左側のスタイルに当てはまるということになる。

なかなかに難しい。