5.

Swiftの配列の使い方|宣言・要素の追加(append)と削除(remove)

編集

Swiftの配列(Array)は、同じ型の値を順序付きで並べて保持するコレクションで、varで宣言すれば要素の追加・削除・変更が行え、letで宣言すると内容を変更できない。本記事では、配列の宣言、要素の追加(appendなど)、削除(remove(at:)など)、アクセス、ループ処理までを最小のコードで示す。

 

この記事の要点
  • 配列は同じ型の値を順序付きで保持するコレクションで、要素には0から始まる添字でアクセスする。
  • 宣言は var a: [Int] = [](空)や var a = [1, 2, 3](初期値あり)のように書く。
  • 追加は append(末尾)・insert(at:)(位置指定)・+=(複数結合)。
  • 削除は remove(at:)removeLast()removeFirst()removeAll()
  • 変更を伴う操作には var が必要。let の配列は内容を変えられない。
  • 範囲外の添字にアクセスすると実行時にクラッシュするため、件数(count)に注意する。

 

配列とは

配列は、同じ型の値を順番に並べて保持するコレクションである。先頭から順に 0, 1, 2, ... という添字(インデックス)が割り当てられ、添字を指定して個々の要素を読み書きする。型は要素の型を角かっこで囲んで [Int](整数の配列)、[String](文字列の配列)のように表す。

Swiftの配列は値型(struct)であり、変数に代入したり関数へ渡したりすると内容がコピーされる。元の配列とコピー先は独立しているため、片方を変更しても他方には影響しない点が特徴である。

 

配列の宣言

配列を宣言する代表的な方法を示す。要素の型が初期値から推論できる場合は型注釈を省略できる。空の配列を作る場合は型注釈が必要になる。

// 初期値ありで宣言(型は推論される)

var a = [1, 2, 3]

 

// 型注釈を付けて宣言

var b: [Int] = [1, 2, 3]

 

// 空の配列(型注釈が必要)

var c: [Int] = []

 

// ジェネリクス構文での宣言(上と同じ意味)

var d = Array<Int>()

 

// 同じ値で埋めた配列(0が5個)

var e = [Int](repeating: 0, count: 5)

 

[Int]Array<Int> の省略記法であり、両者は同じ型を表す。通常は読みやすい [Int] の書き方を使う。

 

書き方 意味
var a = [1, 2, 3] 初期値から型([Int])を推論して宣言
var a: [Int] = [] 空の整数配列を宣言
var a = Array<Int>() ジェネリクス構文での空配列。[Int]() と同じ
[Int](repeating: 0, count: 5) 0を5個並べた配列を作成

 

要素の追加

末尾への追加は append、位置を指定した挿入は insert(at:)、別の配列との結合は += 演算子を使う。

var a = [1, 2, 3]

 

// 末尾に1つ追加 → [1, 2, 3, 4]

a.append(4)

 

// 先頭(添字0)に挿入 → [0, 1, 2, 3, 4]

a.insert(0, at: 0)

 

// 複数の要素をまとめて末尾に追加 → [0, 1, 2, 3, 4, 5, 6]

a += [5, 6]

 

print(a)

 

// 出力: [0, 1, 2, 3, 4, 5, 6]

 

append は1要素を末尾に加える。複数要素をまとめて加えたい場合は append(contentsOf:)+= を使う。insert(at:)at: には 0 から count までの値を指定できる。

 

要素の削除

位置を指定した削除は remove(at:)、末尾は removeLast()、先頭は removeFirst()、全削除は removeAll() を使う。

var a = [10, 20, 30, 40]

 

// 添字1の要素(20)を削除 → [10, 30, 40]

a.remove(at: 1)

 

// 末尾(40)を削除 → [10, 30]

a.removeLast()

 

// 先頭(10)を削除 → [30]

a.removeFirst()

 

// すべて削除 → []

a.removeAll()

 

print(a)

 

// 出力: []

 

メソッド 動作
append(_:) 末尾に1要素を追加する
insert(_:at:) 指定した位置に1要素を挿入する
remove(at:) 指定した位置の要素を削除する
removeLast() 末尾の要素を削除する
removeFirst() 先頭の要素を削除する
removeAll() すべての要素を削除して空にする

 

remove(at:)removeLast()removeFirst() は、削除した要素を戻り値として返す。空の配列に対して removeLast()removeFirst() を呼ぶとクラッシュするため注意する。

 

要素へのアクセス

個々の要素は添字で読み書きする。先頭・末尾の取得や、件数・空かどうかの確認には専用のプロパティがある。

var a = [10, 20, 30]

 

// 添字で読み取り

print(a[0]) // 10

 

// 添字で書き換え

a[0] = 99 // [99, 20, 30]

 

// 先頭・末尾(Optionalで返る)

print(a.first) // Optional(99)

print(a.last) // Optional(30)

 

// 件数と空判定

print(a.count) // 3

print(a.isEmpty) // false

 

firstlast は、配列が空のときに nil を返すため Optional型になる。一方、添字アクセス a[0] は範囲外を指定すると nil ではなくクラッシュする。

 

ループ処理

すべての要素を順番に処理するには for-in ループを使う。添字も併せて使いたい場合は enumerated() を利用する。

let a = [10, 20, 30]

 

// 要素を順に取り出す

for x in a {

    print(x)

}

 

// 添字と要素を同時に取り出す

for (i, x) in a.enumerated() {

    print("\(i): \(x)")

}

 

ループ内で要素を読むだけなら let の配列でも問題ない。ループしながら配列自体に対して追加・削除を行うと、要素数が変わって意図しない結果やクラッシュを招くことがあるため避けるのが無難である。

 

var と let の違い

配列を var で宣言すると、要素の追加・削除・書き換えができる。let で宣言すると配列の内容は変更できず、append などを呼ぶとコンパイルエラーになる。変更を伴う操作には必ず var を使う

let a = [1, 2, 3]

a.append(4) // コンパイルエラー

 

var b = [1, 2, 3]

b.append(4) // OK → [1, 2, 3, 4]

 

落とし穴と注意点

注意点 内容
範囲外アクセスでクラッシュ 添字に 0 未満や count 以上を指定すると実行時エラーで停止する。要素3個の配列で a[3] は不正。
let は変更不可 let で宣言した配列は append や添字代入ができない。変更するなら var にする。
値型のコピー 配列を別の変数へ代入すると内容がコピーされる。一方を変更しても他方は変わらない。
空配列への先頭/末尾削除 空の配列に removeFirst()removeLast() を呼ぶとクラッシュする。isEmpty で確認する。

 

範囲外アクセスを避けるには、添字を使う前に countindices で範囲を確認するとよい。安全に先頭・末尾を取りたい場合は、クラッシュしない first / last を使い、返ってきた Optionalif let などで取り出すのが定石である。

 

よくある質問

Q. 空の配列はどう作りますか?

要素の型が初期値から推論できないため、型注釈を付けて var a: [Int] = [] と書く。var a = [Int]()var a = Array<Int>() でも同じ空配列になる。

Q. 末尾を削除する removeLast()popLast() の違いは?

どちらも末尾を削除するが、removeLast() は空配列で呼ぶとクラッシュする。popLast() は空のとき nil を返すため、空の可能性がある場合は popLast() のほうが安全である。

Q. 特定の値を持つ要素を削除するには?

値から位置を求めて削除する。例えば if let i = a.firstIndex(of: 20) { a.remove(at: i) } のように、firstIndex(of:) で添字を取得してから remove(at:) で削除する。条件で絞り込みたい場合は removeAll(where:) も使える。

 

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. print でデバッグ出力
  2. 変数の宣言
  3. 定数の宣言
  4. データ型
  5. 配列の宣言/追加/削除
  6. クラスとメソッドの作り方と呼び出し方
  7. 繰り返し制御
  8. if文による条件分岐
  9. エラー一覧

最近更新/作成されたページ