【Swift】Arrayの操作方法をまとめてみた

# はじめに
`Array`から要素を追加・削除・取得する場合に、もっと簡単にできる方法があるのでは？と思うことがよくあるので、ドキュメントを確認しながら`追加・削除・取得`用途のものを一部まとめてみました。

## 要素の追加
##### `func append(Element)`
<details><summary>：要素を追加</summary>

```swift
var numbers = [1, 2, 3, 4, 5]
numbers.append(100)
print(numbers)
// Prints "[1, 2, 3, 4, 5, 100]"
```
</details>

##### `func insert(Element, at: Int)`　
<details><summary>：指定した位置に要素を追加</summary>

```swift
var numbers = [1, 2, 3, 4, 5]
numbers.insert(100, at: 3)
numbers.insert(200, at: numbers.endIndex)

print(numbers)
// Prints "[1, 2, 3, 100, 4, 5, 200]"
```
</details>

## 要素の削除
##### `func remove(at: Int) -> Element`
<details><summary>：指定した位置の要素を削除</summary>

```swift
var measurements: [Double] = [1.1, 1.5, 2.9, 1.2, 1.5, 1.3, 1.2]
let removed = measurements.remove(at: 2)
print(measurements)
// Prints "[1.1, 1.5, 1.2, 1.5, 1.3, 1.2]"
```
</details>

##### `func removeFirst() -> Element`
<details><summary>：最初の要素を削除</summary>

```swift
var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeFirst()
print(bugs)
// Prints "["Bumblebee", "Cicada", "Damselfly", "Earwig"]"
```
</details>

##### `func removeLast() -> Element`
<details><summary>：最後の要素を削除</summary>

```swift
var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeLast()
print(bugs)
// Prints "["Aphid",　"Bumblebee", "Cicada", "Damselfly"]"
```
</details>

##### `func removeFirst(Int)`
<details><summary>：指定した数の要素を最初から削除</summary>

```swift
var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeFirst(3)
print(bugs)
// Prints "["Damselfly", "Earwig"]"
```
</details>

##### `func removeLast(Int)`
<details><summary>：指定した数の要素を最後から削除</summary>

```swift
var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeLast(3)
print(bugs)
// Prints "["Aphid", "Bumblebee"]"
```
</details>

##### `func removeSubrange(Range<Int>)`
<details><summary>：指定した範囲の要素を削除</summary>

```swift
var measurements = [1.2, 1.5, 2.9, 1.2, 1.5]
measurements.removeSubrange(1..<4)
print(measurements)
// Prints "[1.2, 1.5]"
```
</details>

##### `func removeAll(where: (Element) -> Bool)`
<details><summary>：条件に合った要素を全て削除</summary>

```swift
var phrase = "The rain in Spain stays mainly in the plain."

let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
phrase.removeAll(where: { vowels.contains($0) })
// phrase == "Th rn n Spn stys mnly n th pln."
```
</details>

##### `func popLast() -> Element?`
<details><summary>：最後の要素を削除＆削除した要素の取得</summary>

```swift
var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
print(bugs.popLast())
print(bugs)

// Prints "Earwig"
// Prints "["Aphid",　"Bumblebee", "Cicada", "Damselfly"]"
```
</details>

## 要素の取得
##### `var first: Element?`
<details><summary>：最初の要素を取得</summary>

```swift
let numbers = [10, 20, 30, 40, 50]
if let firstNumber = numbers.first {
    print(firstNumber)
}
// Prints "10"
```
</details>

##### `var last: Element?`
<details><summary>：最後の要素を取得</summary>

```swift
let numbers = [10, 20, 30, 40, 50]
if let lastNumber = numbers.last {
    print(lastNumber)
}
// Prints "50"
```
</details>

##### `func randomElement() -> Element?`
<details><summary>：ランダムな要素を取得</summary>

```swift
let names = ["Zoey", "Chloe", "Amani", "Amaia"]
let randomName = names.randomElement()!
// randomName == "Amani"
```
</details>

##### `func contains(_ element: Element) -> Bool`(Equatableの場合のみ)
<details><summary>：要素が含まれるかどうか(Equatable)</summary>

```swift
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
print(cast.contains("Marlon"))
// Prints "true"
print(cast.contains("James"))
// Prints "false"
```
</details>

##### `func firstIndex(of: Element) -> Int?`(Equatableの場合のみ)
<details><summary>：要素が含まれる最初のIndexを取得(Equatable)</summary>

```swift
var students = ["Ben", "Ivy", "Jordell", "Maxime"]
if let i = students.firstIndex(of: "Maxime") {
    students[i] = "Max"
}
print(students)
// Prints "["Ben", "Ivy", "Jordell", "Max"]"
```
</details>

##### `func lastIndex(of: Element) -> Int?`(Equatableの場合のみ)
<details><summary>：要素が含まれる最後のIndexを取得(Equatable)</summary>

```swift
var students = ["Ben", "Ivy", "Jordell", "Ben", "Maxime"]
if let i = students.lastIndex(of: "Ben") {
    students[i] = "Benjamin"
}
print(students)
// Prints "["Ben", "Ivy", "Jordell", "Benjamin", "Max"]"
```
</details>

##### `func min() -> Element?`(Comparableの場合のみ)
<details><summary>：最小値を取得(Comparable）</summary>

```swift
let heights = [67.5, 65.7, 64.3, 61.1, 58.5, 60.3, 64.9]
let lowestHeight = heights.min()
print(lowestHeight)
// Prints "Optional(58.5)"
```
</details>

##### `func max() -> Element?`(Comparableの場合のみ)
<details><summary>：最大値を取得(Comparable）</summary>

```swift
let heights = [67.5, 65.7, 64.3, 61.1, 58.5, 60.3, 64.9]
let greatestHeight = heights.max()
print(greatestHeight)
// Prints "Optional(67.5)"
```
</details>

##### `func prefix(Int) -> ArraySlice<Element>`
<details><summary>：指定した数の要素を先頭から全て(配列)取得</summary>

```swift
let numbers = [1, 2, 3, 4, 5]
print(numbers.prefix(2))
// Prints "[1, 2]"
print(numbers.prefix(10))
// Prints "[1, 2, 3, 4, 5]"
```
</details>

##### `func suffix(Int) -> ArraySlice<Element>`
<details><summary>：指定した数の要素を最後から全て(配列)取得</summary>

```swift
let numbers = [1, 2, 3, 4, 5]
print(numbers.suffix(2))
// Prints "[4, 5]"
print(numbers.suffix(10))
// Prints "[1, 2, 3, 4, 5]"
```
</details>

##### `func dropFirst(Int) -> ArraySlice<Element>`
<details><summary>：指定した位置以降の全ての要素(配列)を取得</summary>

```swift
let numbers = [1, 2, 3, 4, 5]
print(numbers.dropFirst(2))
// Prints "[3, 4, 5]"
print(numbers.dropFirst(10))
// Prints "[]"
```
</details>

##### `func dropLast(Int) -> ArraySlice<Element>`
<details><summary>：指定した位置までの全ての要素(配列)を取得</summary>

```swift
let numbers = [1, 2, 3, 4, 5]
print(numbers.dropLast(2))
// Prints "[1, 2, 3]"
print(numbers.dropLast(10))
// Prints "[]"
```
</details>


## 要素を検索して取得
##### `func contains(where: (Element) -> Bool) -> Bool`
<details><summary>：条件に合う要素が含まれるかどうか</summary>

```swift
let expenses = [21.37, 55.21, 9.32, 10.18, 388.77, 11.41]
let hasBigPurchase = expenses.contains { $0 > 100 }
// 'hasBigPurchase' == true
```
</details>

##### `func allSatisfy((Element) -> Bool) -> Bool`
<details><summary>：条件を全ての要素が満たすかどうか</summary>

```swift
let names = ["Sofia", "Camilla", "Martina", "Mateo", "Nicolás"]
let allHaveAtLeastFive = names.allSatisfy({ $0.count >= 5 })
// allHaveAtLeastFive == true
```
</details>

##### `func first(where: (Element) -> Bool) -> Element?`
<details><summary>：条件を満たす最初の要素を取得</summary>

```swift
let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
if let firstNegative = numbers.first(where: { $0 < 0 }) {
    print("The first negative number is \(firstNegative).")
}
// Prints "The first negative number is -2."
```
</details>

##### `func firstIndex(where: (Element) -> Bool) -> Int?`
<details><summary>：条件を満たす最初のIndexを取得</summary>

```swift
var students = ["Ben", "Ivy", "Jordell", "Maxime"]
if let i = students.firstIndex(of: "Maxime") {
    students[i] = "Max"
}
print(students)
// Prints "["Ben", "Ivy", "Jordell", "Max"]"
```
</details>

##### `func last(where: (Element) -> Bool) -> Element?`
<details><summary>：条件を満たす最後の要素を取得</summary>

```swift
let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
if let lastNegative = numbers.last(where: { $0 < 0 }) {
    print("The last negative number is \(lastNegative).")
}
// Prints "The last negative number is -6."
```
</details>

##### `func lastIndex(where: (Element) -> Bool) -> Int?`
<details><summary>：条件を満たす最後のIndexを取得</summary>

```swift
let students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
if let i = students.lastIndex(where: { $0.hasPrefix("A") }) {
    print("\(students[i]) starts with 'A'!")
}
// Prints "Akosua starts with 'A'!"
```
</details>


##### `func filter((Element) -> Bool) -> [Element]`
<details><summary>：条件に合った全ての要素(配列)を取得</summary>

```swift
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let shortNames = cast.filter { $0.count < 5 }
print(shortNames)
// Prints "["Kim", "Karl"]"
```
</details>

## 各要素に処理を加えて取得
##### `func map<T>((Element) -> T) -> [T]`
<details><summary>：処理を加えた全ての要素(配列)を取得</summary>

```swift
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let lowercaseNames = cast.map { $0.lowercased() }
// 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
let letterCounts = cast.map { $0.count }
// 'letterCounts' == [6, 6, 3, 4]
```
</details>

##### `func flatMap<SegmentOfResult>((Element) -> SegmentOfResult) -> [SegmentOfResult.Element]`
<details><summary>：処理を加えた全ての要素を一つの配列にしてから取得</summary>

```swift
let numbers = [1, 2, 3, 4]

let mapped = numbers.map { Array(repeating: $0, count: $0) }
// [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]

let flatMapped = numbers.flatMap { Array(repeating: $0, count: $0) }
// [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
```
</details>

##### `func compactMap<ElementOfResult>((Element) -> ElementOfResult?) -> [ElementOfResult]`
<details><summary>：処理を加えた全てのnil以外の要素(配列)を取得</summary>

```swift
let possibleNumbers = ["1", "2", "three", "///4///", "5"]

let mapped: [Int?] = possibleNumbers.map { str in Int(str) }
// [1, 2, nil, nil, 5]

let compactMapped: [Int] = possibleNumbers.compactMap { str in Int(str) }
// [1, 2, 5]
```
</details>


## その他
### `for-in`ループと`forEach`の違い
##### `func forEach((Element) -> Void)`

```swift
let numberWords = ["one", "two", "three"]
for word in numberWords {
    print(word)
}
// Prints "one"
// Prints "two"
// Prints "three"

numberWords.forEach { word in
    print(word)
}
// Same as above

```

`forEach`では、
- `break`や`continue`を使って、ボディクロージャの現在の呼び出しを終了したり、後続の呼び出しをスキップはできない

- ボディクロージャで`return`を使用すると、ボディクロージャの現在の呼び出しのみから終了し、外部スコープからは終了せず、後続の呼び出しもスキップしない

# おわりに
多すぎて全てを網羅することはできませんでした。。。必要になったものがあれば、都度追記してみたいと思います。表現が間違っている箇所あるかもしれません。ご指摘いただけると嬉しいです。

# 参考
https://developer.apple.com/documentation/swift/array

https://qiita.com/motokiee/items/cf83b22cb34921580a52

https://sarunw.com/posts/different-ways-to-check-string-prefix-in-swift/

`ocumentation/swift/sequence`

https://developer.apple.com/documentation/swift/sequence

`documentation/swift/collection`

https://developer.apple.com/documentation/swift/collection

`documentation/swift/sequence/filter`

https://developer.apple.com/documentation/swift/sequence/3018365-filter