配列で利用できる主なメソッドをまとめてみた[Ruby]

# **はじめに**
プログラムを書くときに配列は欠かせない要素です。
ですので、配列で利用できるメソッドをおさえておくことはアルゴリズムを組む際に大いに助けになります。
配列のリーチできる範囲を把握して、より精細なコードを書けるようになりましょう。


では早速メソッドをまとめていきます。

### **unshift**
配列の先頭に要素を追加します。

```unshift.rb
greeting_informal = ["How's everything?", "What's up?", "How's it going?", "Hi, what's new?"]

p greeting_informal.unshift("Hi, good to see you.")
#=> ["Hi, good to see you.", "How's everything?", "What's up?", "How's it going?", "Hi, what's new?"]
```

### **shift**
配列の先頭の要素を取り出します。破壊的なメソッド。

```shift.rb
greeting_informal = ["How's everything?", "What's up?", "How's it going?", "Hi, what's new?"]

p greeting_informal.shift
#=> "How's everything?"
```

### **push**
配列の末尾に要素を追加します。

```push.rb
greeting_formal = ["Hello, how do you do?", "Hi, it's a pleasure to meet you.", "Hi, good to see you again."]

p greeting_formal.push("How are you?")
#=> ["Hello, how do you do?", "Hi, it's a pleasure to meet you.", "Hi, good to see you again.", "How are you?"]
```

### **pop**
配列の末尾の要素を取り出します。破壊的なメソッド。

```pop.rb
greeting_formal = ["Hello, how do you do?", "Hi, it's a pleasure to meet you.", "Hi, good to see you again."]

p greeting_formal.pop
#=> "Hi, good to see you again."
```

上記4つのメソッドを理解した上で、「列」として配列をみた場合の`キュー`、`スタック`というデータ構造を理解しましょう。
`キュー`は、要素を取り出す際、要素を追加した順に取り出すことができるデータ構造です。これはFIFO(First-in First-out)とも呼ばれています。「最初に入れたものを最初に取り出す」という意味ですね。また、何かを待つ人が、列を作って並んでいる状態と同じなので、待ち行列と呼ばれることもあります。
キューは、`push`メソッドと`shift`メソッドを使って実現します。

`スタック`は、要素を追加した順と逆の順序で要素を取り出していきます。こちらは、LIFO(Last-in First-out)、つまり「最後に入れたものを最初に取り出す」というデータ構造です。要素を追加するときは一番後ろに加え、要素を取り出すときは一番後ろから取る、という感じです。
スタックは、`push`メソッドと`pop`メソッドを使って実現します。

ここで、shiftやpopメソッドは配列の要素を取り出すだけではなく、配列からその要素を削除します。それでは困る場合のために、先頭か末尾の要素を参照するだけのメソッド、`first`、`last`メソッドが用意されています。

### **first**
配列の先頭の要素を参照する

```first.rb
greeting_informal = ["How's everything?", "What's up?", "How's it going?", "Hi, what's new?"]

p greeting_informal.first
#=> "How's everything?"
```

### **last**
配列の末尾の要素を参照する

```last.rb
greeting_formal = ["Hello, how do you do?", "Hi, it's a pleasure to meet you.", "Hi, good to see you again."]

p greeting_formal.last
#=> "Hi, good to see you again."
```

### **concat**
配列aに配列bを連結します。破壊的なメソッド。concatenateの略。

```concat.rb
pleasure_phrase = ["Yes!", "I did it."]
pleasure_phrase.concat(["Bingo!", "Hooray!"])

p pleasure_phrase
#=> ["Yes!", "I did it.", "Bingo!", "Hooray!"]
```


### **freeze**
オブジェクトの内容変更を禁止します。これを使うとオブジェクトは凍結され、変更しようとするとエラーになります。

```freeze.rb
a = [1, 2, 3, 4]

a.freeze
p a.pop
#=> in `pop': can't modify frozen Array (FrozenError)
```

### **dup**
レシーバのオブジェクトのコピーを作成して返します。
先ほどの`freeze`メソッドを使い、一度凍結したオブジェクトを元に戻す方法はありませんが、dupメソッドでコピーしたオブジェクトは凍結されていない状態となります。duplicateの略。

```dup.rb
a = [1, 2, 3, 4]

a.freeze
b = a.dup
p a.pop
#=> in `pop': can't modify frozen Array (FrozenError)
p b.pop
#=> 4
```

### **campact**
配列aの中から要素がnilのものを取り除きます。`compact`は新しい配列を作り、`compact!`は元の配列を置き換えます。compact!メソッドはnilを取り除いた後のaを返しますが、何も取り除けなかったときはnilを返します。
「コンパクトにする」と捉えれば理解しやすいですね。

```compact.rb
a = [1, nil, 3, nil, nil]
a.compact
p a
#=> [1, nil, 3, nil, nil]

a.compact!
p a
#=> [1, 3]
```

### **delete(x)**
配列aから要素xを取り除きます。

```compact.rb
a = [1, nil, 3, nil, nil]

a.delete(nil)
p a
#=> [1, 3]

a.delete(1)
p a
```


### **delete_at(x)**
配列a[x]の要素を取り除きます。

```delete_at.rb
a = [1, nil, 3, nil, nil]

a.delete_at(2)
p a
#=> [1, nil, nil, nil]
```

### **reject**
配列aの各要素について、ブロックを実行した結果、偽になった要素を配列にして返します。
reject!は破壊的なメソッドであり、`delete_if`と同じ挙動を示します。

```reject.rb
a = [1, 2, 3, 4, 5]

a.reject{|i| i > 3}
p a
#=> [1, 2, 3, 4, 5]

a.reject!{|i| i > 3}
p a
#=> [1, 2, 3]
```

### **slice**
配列aから指定された部分を取り除き、取り除いた値を返します。

```reject.rb
a = [1, 2, 3, 4, 5]

p a.slice(1, 2)
#=> [2, 3]
p a
#=> [1, 2, 3, 4, 5]
p a.slice!(1, 2)
#=> [2, 3]
p a
#=> [1, 4, 5]
```

### **uniq**
配列aの重複する要素を削除します。

```uniq.rb
a = [1, 2, 3, 4, 3, 2, 1]

p a.uniq!
#=> [1, 2, 3, 4]
```

### **fill(value)**
配列aの要素をvalueに置き換えます。
引数が1つの場合は、aの要素全てをvalueにします。
引数が2つの場合は、第二引数から、（第三引数）個までをvalueにします。

```fill.rb
a = [1, 2, 3, 4, 5]

p a.fill(0)
#=> [0, 0, 0, 0, 0]
p a
#=> [0, 0, 0, 0, 0]

p [1, 2, 3, 4, 5].fill(0, 2)
#=> [1, 2, 0, 0, 0]
p [1, 2, 3, 4, 5].fill(0, 2, 2)
#=> [1, 2, 0, 0, 5]
```

### **flatten**
配列aを平坦化します。「平坦化」というのは、配列の中に配列が入れ子になっているような場合に、その入れ子を展開して、1つの大きな配列にする操作です。

```flatten.rb
a = [1, [2, [3]], [4], 5]

a.flatten!
p a
#=> [1, 2, 3, 4, 5]
```

### **reverse**
配列aの要素を逆順に並べ替えます。

```reverse.rb
a = [1, 2, 3, 4, 5]

a.reverse!
p a
#=> [5, 4, 3, 2, 1]
```

### **sort**
配列aの各要素を並べ替えます。並べ替え方は、ブロックで指定できます。
ブロックを指定しない場合には、`<=>`演算子を使って比較します。

```sort.rb
a = [2, 4, 3, 5, 1]

a.sort!
p a
#=> [1, 2, 3, 4, 5]
```

### **sort_by**
配列aの要素を並べ替えます。並べ替えは全ての要素についてブロックを評価した結果をソートした順に行われます。

```sort_by.rb
a = [2, 4, 3, 5, 1]

a.sort_by!{|i| -i}
p a
#=> [5, 4, 3, 2, 1
```


### **find_all(or select)**
各要素に対してブロックを実行し、結果が真になる要素だけを配列にして返します。

```find_all.rb
a = [2, 4, 3, 5, 1]

p a.find_all{|i| i == 2 || i == 3}
#=> [2, 3]
```

### **inject(or reduce)**
injectはeachやmapと同じように繰り返しを行うメソッドです。
ブロックを使って繰り返し計算を行うことが特徴で、
`配列オブジェクト.inject {|前の値, 次の値| ブロック処理 }`
のように記述します。
繰り返し順にブロックの要素が配列分加算されていき、ブロックの処理にて計算を行っていきます。
injectは第1引数にinjectが内部で保持している変数の初期値を設定できて、その内部変数がブロックの第1ブロック変数となります。

```inject.rb
array = 1..5

array.inject(0){ |sum,num| p sum + num}
# 1
# 3
# 6
# 10
# 15
array.inject(3){ |sum,num| p sum + num}
# 4
# 6
# 9
# 13
# 18
```

### **count**
引数がなければ要素数を、引数があれば引数と同じ要素数を返します。

```count.rb
a = [2, 4, 3, 5, 1, 2]

p a.count(2)
#=> 2
```

### **empty**
empty?は「入れ物」は存在するのが前提で、配列の中身が空か、文字列の中身が空の場合にtrueを返す。
配列や文字列そのもの（入れ物）が無い場合にはNoMethodErrorが発生する。空ですか？と聞いてるわけだから、少なくとも「入れ物」が存在しないとダメってことですね。

```empty.rb
a = [2, 4, 3, 5, 1, 2]
b = []

p a.empty?
#=> false
p b.empty?
#=> true
```

# **Ruby関連資料**
[Ruby 正規表現まとめ（基礎編）](https://qiita.com/takuyanin/items/2918ffb3151dcfa88565)

# **おわりに**
配列で利用する主なメソッドをまとめてみました。
読んでくださった方がアルゴリズムを組む際に、成功までの道のりを描くにあたって、一助になれば幸いです。