Rubyの組み込みクラスの覚書(Hash)

Ruby技術者認定試験Silver取得のため勉強にあたり、私が知らなかった内容をまとめます。
参考書は[Ruby技術者認定試験合格教本](https://www.amazon.co.jp/%E6%94%B9%E8%A8%822%E7%89%88-Ruby%E6%8A%80%E8%A1%93%E8%80%85%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93%E5%90%88%E6%A0%BC%E6%95%99%E6%9C%AC-Silver-Gold%E5%AF%BE%E5%BF%9C-Ruby%E5%85%AC%E5%BC%8F%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8/dp/4774191949)です。

# Hashクラス
## ハッシュの生成
```ruby

> a = { "apple" => "fruit", "coffee" => "drink" }
=> { "apple" => "fruit", "coffee" => "drink" }
> a.class
=> Hash
```

newメソッドでブロックを取ることで、デフォルト値を設定できる

```ruby

> a = Hash.new { |hash, key| hash[key] = "NONE" }
=> {}
> a["apple"]
=> "NONE"
```

初期値はdefaultメソッドでアクセスできる

```ruby

> a = Hash.new("NONE")
=> {}
> a.default
=> "NONE"
> a.default = "Not Exist"
> a["apple"]
=> "Not Exist"
```

## ハッシュのキーや値を取得する
values_atメソッドはキーに対応する値を**配列**で返す。

```ruby

> a = { 1 => "a", 2 => "b", 3 => "c" }
=> { 1 => "a", 2 => "b", 3 => "c" }
> a.values_at(1, 3)
=> ["a", "c"]
```

fetchメソッドはキーに対応する値を返す。

```ruby

> a = { 1 => "a", 2 => "b", 3 => "c" }
=> { 1 => "a", 2 => "b", 3 => "c" }
> a.featch(1)
=> "a"
```

キーが存在しない場合、二番目の引数が与えられていればその値を、ブロックを与えられていればそのブロックを評価した値を返す。

```ruby

> a = { 1 => "a", 2 => "b", 3 => "c" }
=> { 1 => "a", 2 => "b", 3 => "c" }
> a.featch(5, "NONE")
=> "NONE"
> a.featch(5) { |key| key % 2 == 0 }
=> false
```

selectメソッドとfind_allメソッドは、キーと値の組み合わせについてブロックを評価して、結果が真にとなる組み合わせのみ返す。
selectメソッドではハッシュを、find_allメソッドでは配列を返す。

```ruby

> a = { 1 => "a", 2 => "b", 3 => "c", 4 => "d" }
=> { 1 => "a", 2 => "b", 3 => "c", 4 => "d" }
> a.select { |key, value| key % 2 == 0 }
=> { 2 => "b", 4 => "d" } # selectはハッシュ
> a.find_all { |key, value| key % 2 == 0 }
=>  [[2, "b"], [4, "d"]] # find_allは配列
```

## ハッシュを変更する
rejectメソッドはブロックを評価した結果が真になる値を取り除いたハッシュを生成して返す

```ruby

> a = { "apple" => "fruit", "coffee" => "drink" }
=> { "apple" => "fruit", "coffee" => "drink" }
> a.reject { |key, value|  value == "drink" }
=> { "apple" => "fruit" }
> a
=> { "apple" => "fruit", "coffee" => "drink" } # もとの値は変更されない
```

reject!メソッドとdelete_ifメソッドはrejectメソッドの破壊的メソッド版。 
ブロックを評価した結果が真になる値を取り除く。

```ruby

> a = { "apple" => "fruit", "coffee" => "drink" }
=> { "apple" => "fruit", "coffee" => "drink" }
> a.reject! { |key, value|  value == "drink" }
=> { "apple" => "fruit" }
> a
=> { "apple" => "fruit" } # もとの値が変更される
```

replaceメソッドは、引数で与えられたハッシュで自分自身を書き換える。object_idは変わらない。

```ruby

> a = { "apple" => "fruit", "coffee" => "drink" }
=> { "apple" => "fruit", "coffee" => "drink" }
> a.object_id
=> 2190908200
> a.replace({ "orange" => "fruit", "tea" => "drink" })
=> { "orange" => "fruit", "tea" => "drink" }
> a
=> { "orange" => "fruit", "tea" => "drink" }
> a.object_id
=> 2190908200
```

mergeメソッドは、自分自身と引数で指定されたハッシュをマージしたハッシュオブジェクトを返す。  

```ruby

> a = { "apple" => "foods", "coffee" => "drink" }
=> { "apple" => "foods", "coffee" => "drink" }
> a.merge({ "orange" => "fruit", "tea" => "drink", "apple" => "fruit" })
=> { "apple" => "fruit", "coffee" => "drink", "orange" => "fruit", "tea" => "drink" }
> a
> => { "apple" => "foods", "coffee" => "drink" } # もとの値は変更されない
```

merge!メソッドとupdateメソッドはmergeの破壊的メソッド版

```ruby

> a = { "apple" => "foods", "coffee" => "drink" }
=> { "apple" => "foods", "coffee" => "drink" }
> a.merge!({ "orange" => "fruit", "tea" => "drink", "apple" => "fruit" })
=> { "apple" => "fruit", "coffee" => "drink", "orange" => "fruit", "tea" => "drink" }
> a
> => { "apple" => "fruit", "coffee" => "drink", "orange" => "fruit", "tea" => "drink" } # もとの値が変更される
```