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