Ruby 配列、ハッシュ

動作環境はMacです。

**puts,print,p,ppメソッドの違い**

```irb

irb(main):002:0> puts 'kaneko'
kaneko
=> nil　#変数の内容に改行を加えてメソッドの戻り値をターミナルに出力
irb(main):003:0> print 'kaneko'
kaneko=> nil　　
#改行なしでメソッドの戻り値をターミナルに出力
irb(main):004:0> p 'kaneko'
"kaneko"
=> "kaneko"　#pメソッドの戻り値は引数のオブジェクト　デバック向け。
#デバックとはプログラムの不具合を見つけて修正すること。

ppメソッドはpメソッドより適切な改行をして出力する。
pメソッドで適切でない場合は、ppメソッドを使う。
```

##配列##

- 複数のデータを格納できるオブジェクト。
- 配列内のデータは順番に並んでいて、添字(インデックス)を指定することで取り出すことができる。

**配列の作成方法**

- 空の配列を作る
[]

- 3つの要素が格納された配列を作る
[要素1,要素2,要素3]

**実践**

```irb
irb(main):003:0> a = [1, 2, 3, 'aa', [1, 2, 3]]  #変数aに配列を代入
=> [1, 2, 3, "aa", [1, 2, 3]]
irb(main):004:0> a[0]　
=> 1
irb(main):005:0> a[1]
=> 2
irb(main):006:0> a[3]
=> "aa"
irb(main):007:0> a[2]
=> 3
irb(main):008:0> a[4]
=> [1, 2, 3]
irb(main):009:0> puts a
1
2
3
aa
1
2
3
=> nil
irb(main):010:0> p a
[1, 2, 3, "aa", [1, 2, 3]]
=> [1, 2, 3, "aa", [1, 2, 3]]
irb(main):011:0> pp a
NoMethodError: undefined method `pp' for main:Object
Did you mean?  p
	from (irb):11
	from /Users/toripurug884/.rbenv/versions/2.4.1/bin/irb:11:in `<main>'
irb(main):012:0> a.empty?　#変数aが空か？
=> false
irb(main):013:0> b = []　
=> []
irb(main):014:0> b.empty?
=> true
irb(main):015:0> a.include?('aa') #変数aに'aa'が含まれるか？
=> true
irb(main):016:0> a.include?('a')
=> false
irb(main):017:0> a.reverse　#配列の中身を反転
=> [[1, 2, 3], "aa", 3, 2, 1]
irb(main):018:0> a
=> [1, 2, 3, "aa", [1, 2, 3]]
irb(main):019:0> a.reverse!　#配列の中身を反転させる破壊的メソッド
=> [[1, 2, 3], "aa", 3, 2, 1]
irb(main):020:0> a
=> [[1, 2, 3], "aa", 3, 2, 1]
irb(main):021:0> a.shuffle　 #配列の中身をランダムに入れ替え
=> [2, 3, 1, "aa", [1, 2, 3]]
```

配列を使ったメソッド（数値）

```irb
irb(main):022:0> (0..25).to_a #範囲オブジェクトを指定し、配列へ
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
irb(main):024:0> a = (0..99).to_a.shuffle!　#オブジェクトの中身を破壊的メソッドでランダムに入れ替える
=> [17, 1, 46, 12, 62, 69, 39, 40, 96, 87, 77, 50, 84, 56, 70, 7, 98, 19, 64, 8, 67, 89, 14, 33, 20, 29, 22, 51, 26, 18, 68, 57, 86, 47, 55, 48, 97, 44, 34, 42, 79, 30, 61, 6, 81, 13, 85, 0, 59, 71, 65, 99, 75, 72, 23, 66, 63, 5, 15, 49, 91, 36, 35, 38, 94, 45, 95, 11, 41, 2, 4, 10, 31, 54, 88, 43, 32, 28, 73, 92, 3, 58, 80, 16, 27, 82, 52, 25, 9, 60, 90, 74, 93, 21, 24, 83, 37, 53, 78, 76]
irb(main):025:0> a　　#中身が入れ替わる
=> [17, 1, 46, 12, 62, 69, 39, 40, 96, 87, 77, 50, 84, 56, 70, 7, 98, 19, 64, 8, 67, 89, 14, 33, 20, 29, 22, 51, 26, 18, 68, 57, 86, 47, 55, 48, 97, 44, 34, 42, 79, 30, 61, 6, 81, 13, 85, 0, 59, 71, 65, 99, 75, 72, 23, 66, 63, 5, 15, 49, 91, 36, 35, 38, 94, 45, 95, 11, 41, 2, 4, 10, 31, 54, 88, 43, 32, 28, 73, 92, 3, 58, 80, 16, 27, 82, 52, 25, 9, 60, 90, 74, 93, 21, 24, 83, 37, 53, 78, 76]
irb(main):026:0> z = (0..10).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):027:0> z[0]
=> 0
irb(main):028:0> z[1]
=> 1
irb(main):029:0> z
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):030:0> z << 20　#末尾に20を追加　pushとイコール
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]
irb(main):031:0> z.push(30)　#末尾に30を追加　<<とイコール
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30]
irb(main):033:0> z.pop　#末尾の数値を削除
=> 30
irb(main):034:0> z
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]
irb(main):035:0> z.shift　#先頭の数値を削除
=> 0
irb(main):036:0> z << 3
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3]
irb(main):037:0> z
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3]
irb(main):038:0> z << 3
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3, 3]
irb(main):039:0> z << 6
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3, 3, 6]
irb(main):040:0> z
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3, 3, 6]
irb(main):041:0> z.uniq #被っている数値を出力しない
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]
irb(main):042:0> z.uniq!　#破壊的メソッド
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]
irb(main):043:0> z　#3と6が出力されない
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]
```

配列を使ったメソッド（文字列）

```irb
irb(main):044:0> a = [ "my", "name", "is", "nakamura"]
=> ["my", "name", "is", "nakamura"]
irb(main):045:0> a
=> ["my", "name", "is", "nakamura"]
irb(main):046:0> a.join　 #配列の中身を結合
=> "mynameisnakamura"
irb(main):048:0> a.join(' ')　#配列の中身を結合し、スペースを開ける　スプリット
=> "my name is nakamura"
irb(main):049:0> a.join('_')
=> "my_name_is_nakamura"
irb(main):050:0> a.sort　#配列の中身を入れ替える
=> ["is", "my", "nakamura", "name"]
irb(main):051:0> a.sort.reverse　#配列の中身を逆にする
=> ["name", "nakamura", "my", "is"]
irb(main):053:0> a
=> ["my", "name", "is", "nakamura"]
irb(main):054:0> a.sort!.reverse!　　#破壊的メソッド
=> ["name", "nakamura", "my", "is"]
irb(main):055:0> a.size　#配列に入っているデータ数の出力
=> 4
```

##ハッシュ

- キー（key）と値(value)でデータの管理をするオブジェクト
- 連想配列、マップ、ディクショナリと呼ばれる場合もある

**作成方法**

空のハッシュを作成
{}

キーと値の組み合わせを３つ格納するハッシュ
{ キー1 => 値1, キー2 => 値2, キー3 => 値3 }

---

**実践**

```irb
irb(main):001:0> {}
=> {} #空のブランケット作成
irb(main):002:0> kaneki = {'name' => 'ken', 'birthplace' => 'saga'}　#変数kanekiにハッシュで代入
=> {"name"=>"ken", "birthplace"=>"saga"}
irb(main):003:0> kaneki　
=> {"name"=>"ken", "birthplace"=>"saga"}
irb(main):007:0> puts kaneki['name']
ken
=> nil #nameキーを出力
irb(main):009:0> puts kaneki['birthplace']
saga #birthplaceキーを出力
=> nil
irb(main):010:0> kaneki['age'] = 20
=> 20　#ageキーを追加
irb(main):011:0> kaneki
=> {"name"=>"ken", "birthplace"=>"saga", "age"=>20}
irb(main):013:0> kaneki['age'] = 21
=> 21　#ageキーを書き換え
irb(main):014:0> kaneki
=> {"name"=>"ken", "birthplace"=>"saga", "age"=>21}
irb(main):017:0> kaneki.delete('age')　#ageキーを削除
=> 21
irb(main):019:0> puts kaneki
{"name"=>"ken", "birthplace"=>"saga"}
=> nil
```

**シンボル**

・ソースコード上は文字列に見えるが、内部では整数として扱われる
・文字列を使う場合よりシンボルを使った方が処理が速い


---

**実践**

```irb 

irb(main):031:0> imawano.keys #変数が持つキーを出力
=> [:name, :birthplace]
irb(main):032:0> imawano.values　#変数が持つ値の出力
=> ["kiyosirou", "okinawa"]
irb(main):034:0> imawano.has_key?(:name)#変数が引数に渡されるキーを持っているか？
=> true　#持っているのでtrue
irb(main):035:0> imawano.has_key?(:id)
=> false 　#持っていないのでfalse
irb(main):036:0> imawano.size　#変数に入っているキーの数
=> 2 
```