【Swift】構造体の要素を検索してインデックスを取得する方法!

この記事からわかること
- Swiftで構造体の要素インデックスを取得するには?
- firstやfilter、firstIndexの使い方
- Equatableプロトコルとは?
- 構造体やクラスを比較する方法
index
[open]
\ アプリをリリースしました /
環境
- Xcode:15.0.1
- iOS:17.0
- watchOS:10.0
- Swift:5.9
- macOS:Sonoma 14.1
Swiftで構造体を扱うときにデータ内の特定の要素やそのインデックス番号を検索して取得する方法をまとめていきます。
構造体の中の要素を検索して取得する
扱う[構造体]
配列内に特定の構造体の要素が格納されている際に指定の値を持つ要素を取得するにはfirst
メソッドまたはfilter
メソッドを使用します。
両者の違いは返り値として取得できる要素数の違いです。first
メソッドは最初にマッチした要素1つ、filter
メソッドはマッチした要素全てを返します。
firstメソッド
返り値は条件にマッチした要素1つ。ない場合はnil
を返します。
filterメソッド
返り値は条件にマッチした要素全て。ない場合は空の配列を返します。
firstメソッドの使い方
first
メソッドは配列に対して使用できるメソッドでfirst(where:)
形式を使えば要素の値に条件式を渡してマッチする要素を検索することができます。
クロージャ内では$0
で疑似的な要素(構造体)に参照することができ、さらにプロパティにはドットシンタックスを使って$0. プロパティ
でアクセスできます。
条件で検索してマッチする構造体を取得
またwhere
を省略して以下のように記述することも可能です。
filterメソッドの使い方
filter
メソッドの使い方はfirst
メソッドとは異なり条件式を渡す際のwhere
は必要ありません。そのままクロージャの中に条件を指定しマッチした要素がコレクション形式で取得できます。
条件で検索してマッチする構造体を取得
以下の形式でもOKです。
構造体の中の要素を検索してインデックスを取得する
配列内に特定の構造体の要素が格納されている際に指定の値(構造体)を持つ要素インデックスを取得するにはfirstIndex
メソッドを使用します。
firstIndex
メソッドはfirstIndex(of:)
形式で使用します。引数of
には値を渡し、その値と完全に一致する要素のインデックス番号
を返します。
条件で検索してマッチする構造体を取得
しかし上記のコードでは以下のようなエラーが発生してしまいます。
これを解決するには構造体がEquatable
プロトコルに準拠している必要があります。
Equatableプロトコルとは?
Equatable
プロトコルはオブジェクトを比較可能にできるようにするプロトコルです。
比較するプロパティを変更する
Equatable
プロトコルを準拠させた構造体の比較は全てのプロパティの値が一致しているかを識別しています。なので以下のように1つのプロパティの値が違うインスタンス同士は一致していないとみなされ何も出力されません。
「言語名が同じであれば一致していることにしたい」場合はEquatable
プロトコルに準拠させた構造体に==
メソッドを静的メソッドとして実装することでカスタムできます。
これで再度同じ比較を試してみると期待通り「同じ言語を使用します」が出力されました。
クラスを比較できるようにする
インスタンス(オブジェクト)の比較は構造体だけでなくクラスでも同じです。クラスのインスタンス同士をそのまま比較しようとすると同様のエラーが出てしまいます。
クラスの場合も比較対象にするプロパティを明示的に==メソッドを静的メソッドとして実装しなければいけません。
私がSwift UI学習に使用した参考書
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。