Ruby: Enumeratorクラス
REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。
問題
実行したらどうなるか
(10..15).to_a.map.with_index(1) do |elem, i| puts i end
解答
正解は
1
2
3
4
5
6
です
解説
Enumerator#with_index
with_index(offset = 0) {|(*args), idx| ... } -> object
- 生成時のパラメータに従って、要素にインデックスを添えて繰り返します。
- インデックスは offset から始まります
引用: instance method Enumerator#with_index (Ruby 2.1.0)
似てる Enumerable#each_with_index
- offset 引数を受け取らない
実行して確かめる
p "------------------" p (10..15).to_a p "------------------" (10..15).to_a.map do |elem| p elem end p "------------------" (10..15).to_a.map.with_index do |elem, i| p [elem, i] end p "------------------" (10..15).to_a.map.with_index(1) do |elem, i| p [elem, i] end p "------------------" (10..15).to_a.map.each_with_index do |elem, i| p [elem, i] end
"------------------" [10, 11, 12, 13, 14, 15] "------------------" 10 11 12 13 14 15 "------------------" [10, 0] [11, 1] [12, 2] [13, 3] [14, 4] [15, 5] "------------------" [10, 1] [11, 2] [12, 3] [13, 4] [14, 5] [15, 6] "------------------" [10, 0] [11, 1] [12, 2] [13, 3] [14, 4] [15, 5]
Ruby: Enumerableモジュール
REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。
問題
以下の実行結果として正しいものを選択しなさい。
p [1, 2, 3].inject{|x, y| x + y ** 2} rescue p $! p [1, 2, 3].inject(0){|x, y| x + y ** 2} rescue p $! p [1, 2, 3].inject([]){|x, y| x << y ** 2} rescue p $! p [1, 2, 3].inject do|x, y| x + y ** 2 end rescue p $!
選択肢
選択肢 | 1行目 | 2行目 | 3行目 | 4行目 |
---|---|---|---|---|
[1] | 14 | 14 | [1, 4, 9] | 14 |
[2] | 14 | 0 | [] | 14 |
[3] | 14 | 14 | [1, 4, 9] | |
[4] | 14 | [1, 4, 9] |
解答
正解は [3] です
解説
inject(init = self.first) {|result, item| ... } -> object
- 最初に初期値 init と self の最初の要素を引数にブロックを実行します。
- 2 回目以降のループでは、前のブロックの実行結果と self の次の要素を引数に順次ブロックを実行します。
- そうして最後の要素まで繰り返し、最後のブロックの実行結果を返します。
引用: instance method Enumerable#inject (Ruby 2.1.0)
1行目
begin [1, 2, 3].inject {|x, y| print sprintf("%d + %d ** 2 = ", x, y) p x + y ** 2 } rescue p $! end
1 + 2 ** 2 = 5 5 + 3 ** 2 = 14
2行目
begin [1, 2, 3].inject(0) {|x, y| print sprintf("%d + %d ** 2 = ", x, y) p x + y ** 2 } rescue p $! end
0 + 1 ** 2 = 1 1 + 2 ** 2 = 5 5 + 3 ** 2 = 14
3行目
begin [1, 2, 3].inject([]) {|x, y| print sprintf("%s << %d ** 2 = ", x.to_s, y) p x << y ** 2 } rescue p $! end
[] << 1 ** 2 = [1] [1] << 2 ** 2 = [1, 4] [1, 4] << 3 ** 2 = [1, 4, 9]
Ruby: Stringクラスのメソッド
REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。
問題
次のコードを実行するどどうなりますか
arr = [1,2].product([3,4]).transpose p arr
選択肢
[[1, 3], [1, 4], [2, 3], [2, 4]]
と表示される[[1, 3], [2, 4]]
と表示される[1, 2]
と表示される[[1, 1, 2, 2], [3, 4, 3, 4]]
と表示される
解答
正解は [4] です
解説
.product
- 配列からそれぞれ1つ要素を取り出し、新しい配列を作る
例: [1,2].product([3,4])
product | 3 | 4 |
---|---|---|
1 | [1, 3] | [1, 4] |
2 | [2, 3] | [2, 4] |
.transpose
- 行と列を入れ替えた配列を作る
- 一次元の配列に対しては、例外 TypeError が発生する
arr = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ].transpose p arr # => [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
参考: instance method Array#transpose (Ruby 2.1.0)
問題
次のコードを実行するとどうなりますか
a = "Ruby" b = " on Rails" a.concat b a.reverse p a.index("R", 1)
解答
正解は 8 です
解説
String#index(pattern, pos)
- 文字列のpos番目からpatternを検索し、最初に見つかった位置を返します
- 位置は左端が
0
で、1文字ずつ増えてく感じ
R | u | b | y | o | n | R | a | i | l | s | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
irbでの実行結果
irb(main):001:0> a = "Ruby" => "Ruby" irb(main):002:0> b = " on Rails" => " on Rails" irb(main):003:0> a.concat b => "Ruby on Rails" irb(main):004:0> a.reverse => "sliaR no ybuR" irb(main):005:0> a => "Ruby on Rails" irb(main):006:0> a.index("R", 1) => 8
Ruby: Stringクラスの文字列フォーマット
REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。
問題
次のコードを実行するとどうなりますか
p "Hello%d" % 5
選択肢
"HelloHelloHelloHelloHello"
と表示される"Hello"
と表示される"Hello5"
と表示される- エラーになる
解答
正解は [3] です
解説
指示子
- Stringクラスの
%
はフォーマットされた文字列を返します。 - 指示子は引数の型の解釈を示します。(指示子 = %の右側の記号)
- 指示子を省略することはできません。
- 指示子には大きく分けて3種類あります。
- 文字列を表す指示子: c, s, p
- 整数を表す指示子: d, i, u, b, B, o, x, X,
- 浮動小数点数を表す指示子: f, g, e, E, G
Ruby: 時刻フォーマット文字列
REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。
問題
d = Date.new(2015, 1, 5)
の時、出力結果が01/05/15
になるのはどれ?
選択肢
puts d.strftime("%x")
puts d.strftime("%m/%d/%Y")
puts d.strftime("%m/%D/%y")
puts d.strftime("%M/%d/%y")
解答
正解は [1] です
解説
フォーマット文字列の意味
- 『年・月・日』
%C
: 世紀 (2009年であれば 20)%Y
: 西暦を表す数%y
: 西暦の下2桁(00-99)%B
: 月の名称(January, February ... )%b
: 月の省略名(Jan, Feb ... )%h
: %b と同等%m
: 月を表す数字(01-12)%d
: 日(01-31)%e
: 日。一桁の場合、半角空白で埋める ( 1..31)
- 『曜日・週数・日数』
%A
: 曜日の名称(Sunday, Monday ... )%a
: 曜日の省略名(Sun, Mon ... )%w
: 曜日を表す数。日曜日が0(0-6)%u
: 月曜日を1とした、曜日の数値表現 (1..7)%U
: 週を表す数。最初の日曜日が第1週の始まり(00-53)%W
: 週を表す数。最初の月曜日が第1週の始まり(00-53)%V
: ISO 8601形式の暦週 (01..53)%j
: 年中の通算日(001-366)
- 『時・分・秒』
- 『午前午後』
%P
: 午前または午後(am,pm)%p
: 午前または午後(AM,PM)
- 『合わせ技』
%D
: 日付 (%m/%d/%y)%x
: 同上%F
: %Y-%m-%d と同等 (ISO 8601の日付フォーマット)%v
: VMS形式の日付 (%e-%b-%Y)%c
: 日付と時刻%X
: 時刻%R
: 24時間制の時刻。%H:%M と同等。%T
: 24時間制の時刻。%H:%M:%S と同等。%r
: 12時間制の時刻。%I:%M:%S %p と同等。
- 『タイムゾーン』
- 『その他』
%n
: 改行 (\n)%t
: タブ文字 (\t)%%
: %自身
参考: instance method Time#strftime (Ruby 2.1.0)
実際の出力
require 'date' d = Date.new(2015, 1, 5) puts d.strftime("%x") puts d.strftime("%m/%d/%Y") puts d.strftime("%m/%D/%y") puts d.strftime("%M/%d/%y")
01/05/15 01/05/2015 01/01/05/15/15 00/05/15
Ruby: 2進数/8進数/16進数
REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。
問題
エラーが発生するのはどれですか
選択肢
puts "0x90".hex
puts '90'
puts 0b2
puts '80'.oct
解答
正解は [3] です
解説
数値のプレフィックス
num = 0d1234 // 10進数 (0dで始まる数値は10進数とみなされる) num = 0xffff // 16進数 (0xで始まる数値は16進数とみなされる) num = 0o777 // 8進数 (0oで始まる数値は 8進数とみなされる) num = 0b11000100 // 2進数 (0bで始まる数値は 2進数とみなされる)
文字列を数値変換するメソッド
- Stringクラス
.hex
: 16進数の文字列表現とみなして、10進数の整数に変換する.oct
: 8進数の文字列表現とみなして、 〃- oct は文字列のプレフィックスに応じて 8 進以外の変換も行います。
p "0b10".oct # => 2
p "0x10".oct # => 16
.to_i
: 10進数の文字列表現とみなして、 〃.to_f
: 10進数の文字列表現とみなして、10進数の浮動小数点数 Float に変換する
- Kernelモジュール
Integer()
: 引数を整数に変換した結果を返しますFloat()
: 引数を浮動小数点数 Float に変換した結果を返します
参考,引用: class String (Ruby 2.5.0)
実際の実行結果
irb(main):001:0> puts "0x90".hex 144 => nil irb(main):002:0> puts '90' 90 => nil irb(main):003:0> puts 0b2 SyntaxError: (irb):3: numeric literal without digits puts 0b2 ^ from /your/path/... irb(main):004:0> puts '80'.oct 0 => nil
Ruby: ヒアドキュメントの扱い
REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。
問題
次のコードを実行するとどうなりますか
s = <<'EOF' Hello, Ruby EOF 'EOF' p s
選択肢
"Hello,\nRuby\n"
と表示される"Hello,\nRuby\nEOF"
と表示される"Hello,Ruby"
と表示される- エラーが発生する
解答
正解は [1] です
解説
<<'EOF'
からEOF
までがヒアドキュメント'EOF'
はただの文字列出力p
は改行コード¥n
を表示するputs
/print
/printf
は実際に改行した文字列を表示する
- 開始ラベル
"識別子"
: 式展開が有効識別子
: 同上'識別子'
: 式展開できない`識別子`
: コマンド出力