本日の素振り。
[arst_toc tag=\"h3\"]
配列
配列はArrayクラスのインスタンス。
a = Array.new(3) # [nil,nil,nil]
b = Array.new(2,\"hoge\") # [\"hoge\",\"hoge\"]
配列は[]で表す。
a = [10,20,30] # [10,20,30]
a[1] # 20
b = [20,true,\"hoge\"] # [10,true,\"hoge\"]
b[2] # \"hoge\"
b[3] # nil
%記法で配列生成
配列の要素が文字列である場合に限って、%W、%wによって文字列を配列化できる。
デリミタは半角スペース、%Wでダブルクォート、%wでシングルクォート(なし)。
自動的にダブルクォート、シングルクォートで括るため、
文字列の配列を作るためにダブルクォート、シングルクォートで汚すことを防げる。
p = %W(hoge fuga) # [\"hoge\",\"fuga\"]
q = %w(hoge fuga) # [\'hoge\',\'fuga\']
joinで配列結合
配列と配列を結合して新しい配列を作るのではなく、要素を文字列として結合する。
p = [100,200,300] # [100,200,300]
p.join # \"100200300\"
p.join(\"_\") # \"100_200_300\"
配列の生成
Array.new()を使うと同じオブジェクトを持つ配列を作れる。
要素分の変数が確保されるのではなく、指定した値を持つ変数が1つ確保されて並ぶ。
a = Array.new(2,\"hoge\") # [\"hoge\", \"hoge\"]
a.object_id # 4032
b.object_id # 4032
a[0].replace(\'fuga\') # [\"fuga\", \"fuga\"]
a.object_id # 4032
b.object_id # 4032
Array.new(){}だと要素数分の変数が確保されて並ぶ。
a = Array.new(2){\'hoge\'} # [\"hoge\", \"hoge\"]
a[0].object_id # 4033
a[1].object_id # 4034
範囲外アクセス
配列の大きさを超えてアクセスしたとき、例外とならず、アクセスしたところまで配列が広がる。
最初の位置から作った最後の位置までnilで埋められる。
a = Array.new(3){\"hoge\"} # [\"hoge\",\"hoge\",\"hoge\"]
a[5] = \"fuga\" # [\"hoge\",\"hoge\",\"hoge\",nil,nil,\"fuga\"]
負の添え字アクセス
何が何でもコード行を削減したい意思!
配列に負の添え字でアクセスすると\"末尾から数えた位置\"という意味になる。
a = [\"hoge1\", \"hoge2\", \"hoge3\"] # [\"hoge1\", \"hoge2\", \"hoge3\"]
a[-1] # \"hoge3\"
配列のスライス
phpのarray_slice()に相当するやつ。指定したインデックスから何個分というやつ。
a = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6]
a[2,3] # [2, 3, 4]
以下のように指定したインデックスから何個分を置き換えられる。
a = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6]
a[1,2] = \"hoge\" # [0, \"hoge\", 3, 4, 5, 6]
b = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6]
b[1,2] = \"hoge\", \"fuga\" # [0, \"hoge\",\"fuga\", 3, 4, 5, 6]
c = [0, 1, 2, 3, 4, 5, 6] # [0, 1, 2, 3, 4, 5, 6]
c[1,2] = \"hoge1\", \"hoge2\", \"hoge3\" # [0, \"hoge1\",\"hoge2\",\"hoge3\", 3, 4, 5, 6]
複数の戻り返却と多重代入
複数の値を返す関数を定義する。複数の値を返すように見えるが配列が返っている。
def test
return \"hoge1\", \"hoge2\", \"hoge3\"
end
a, b, c = test # [\"hoge1\", \"hoge2\", \"hoge3\"]
a # \"hoge1\"
b # \"hoge2\"
c $ \"hoge3\"
戻りとしてネストした配列を返すことができて、同じ構造の変数に代入できる。(多重代入)
def test2
return [[\"hoge1\", \"hoge2\"], \"hoge3\"]
end
(x,y),z = test2 # [[\"hoge1\",\"hgoe2\"], \"hoge3\"]
+、-演算子
左オペランドと右オペランドの要素の加算、左オペランドから右オペランドの減算
a = [\"hoge1\",\"hoge2\"] # [\"hoge1\",\"hoge2\"]
b = [\"hoge2\",\"hoge3\"] # [\"hoge2\",\"hoge3\"]
a + b # [\"hoge1\",\"hoge2\",\"hoge2\",\"hoge3\"]
a - b # [\"hoge1\"]
b - a # [\"hoge3\"]
減算の場合、左オペランドに重複があるときは全て削除される
x = [\"hoge1\",\"hoge1\",\"hoge2\"] # [\"hoge1\",\"hoge2\",\"hoge3\"]
y = [\"hoge1\"]
x - y # [\"hoge2\",\"hoge3\"]
*演算子
右オペランドが数値の場合は左オペランドをその回数繰り返す。
右オペランドが文字列の場合はjoinと同じ。
a = [1,2,3]
a * 2 # [1,2,3,1,2,3]
for式,each式
PHPのforeachに近いforとeach。forは期待と異なりループの中と外はスコープが同じ。
for内の変数をfor外でアクセスできる。
for value in [100,200,300]
inner_loop = 500
end
inner_loop + 100 # 600
対してeachはループ内とループ外でスコープが異なりeach内の変数はeach外で未初期化。
[100,200,300].each do
inner_look2 = 500
end
inner_loop # undefined variable