Swiftの比較演算子!12の実践的な使い方とサンプルコード – JPSM

Swiftの比較演算子!12の実践的な使い方とサンプルコード

Swiftの比較演算子を図解したイラストSwift

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

また、理解しにくい説明や難しい問題に躓いても、JPSMがプログラミングの解説に特化してオリジナルにチューニングした画面右下のAIアシスタントに質問していだければ、特殊な問題でも指示に従い解決できるように作ってあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

皆さん、Swiftの比較演算子を知っていますか?SwiftはiOSやmacOSのアプリ開発に広く使われている言語です。

初心者から上級者まで、この記事でSwiftの比較演算子の魅力を再発見し、その使い方を深く理解する手助けをしたいと思います。

この記事を通じて、Swiftの比較演算子の使い方や注意点、さらにはカスタマイズ方法までをマスターできるようになります。

●Swiftの比較演算子とは

比較演算子は、名前の通り、2つの値を比較するための演算子です。

Swiftでは、数値や文字列などのデータ型の値を比較するために使用します。

これにより、条件分岐やループなどの制御文で、特定の条件が満たされた場合のみ処理を実行することができます。

○比較演算子の基本概念

Swiftにおける基本的な比較演算子には次のようなものがあります。

  1. ==:等しいかどうかを判断する
  2. !=:等しくないかどうかを判断する
  3. >:左側の値が右側より大きいかどうかを判断する
  4. <:左側の値が右側より小さいかどうかを判断する
  5. >=:左側の値が右側以上かどうかを判断する
  6. <=:左側の値が右側以下かどうかを判断する

これらの比較演算子は、真偽値(Bool型のtrueまたはfalse)を返します。

したがって、これらの結果をもとにif文やwhile文などの制御文での条件判断を行うことが可能です。

Swiftの比較演算子は、数値の比較だけでなく、文字列の比較にも使用できます。

ただし、文字列の比較の際は、文字列の辞書順(アルファベット順や日本語のあいうえお順)で大小が判定されることを覚えておきましょう。

●Swiftの比較演算子の具体的な使い方

比較演算子の基本概念を理解したところで、具体的な使い方をSwiftのサンプルコードを交えて解説していきます。

初心者の方でもしっかりと追いやすいよう、一つ一つのコードの意味や動きを丁寧に説明します。

○サンプルコード1:等価性を確認する

Swiftでの等価性を確認するための最も基本的な比較演算子は ==!= です。

ここではその使い方のサンプルコードを紹介します。

let a = 5
let b = 7
let c = 5

if a == c {
    print("aとcは等しい")
} else {
    print("aとcは等しくない")
}

if a != b {
    print("aとbは等しくない")
} else {
    print("aとbは等しい")
}

このコードでは、整数型の変数a, b, cの等価性を比較しています。

この例では、acの値が同じであるため「aとcは等しい」と表示され、abは異なる値であるため「aとbは等しくない」と表示されます。

○サンプルコード2:数値の大小を判断する

次に、数値の大小を判断するための比較演算子、<><=>=の使用方法を見ていきます。

let x = 10
let y = 20

if x < y {
    print("xはyより小さい")
}

if x > y {
    print("xはyより大きい")
} else {
    print("xはy以下")
}

if x >= 10 {
    print("xは10以上")
}

if y <= 20 {
    print("yは20以下")
}

このサンプルコードでは、整数型の変数xとyの値を比較しています。

xyより小さいため「xはyより小さい」と表示されます。

また、xは10と等しいため「xは10以上」と表示され、「yは20以下」とも表示されます。

○サンプルコード3:文字列の比較

Swiftでは、文字列の比較も簡単に行うことができます。

等価性や大小を確認するための比較演算子を使用して、文字列同士を比較することができます。

下記のサンプルコードは、文字列の等価性を確認する方法を表しています。

let stringA = "Hello"
let stringB = "Hello"
let stringC = "hello"

// 等価性の確認
if stringA == stringB {
    print("stringAとstringBは等しい")
}

if stringA != stringC {
    print("stringAとstringCは異なる")
}

このコードでは、stringAstringBは同じ値「Hello」であるため、”stringAとstringBは等しい”と表示されます。

一方、stringAstringCは異なるため、”stringAとstringCは異なる”と表示されます。

次に、文字列の大小の比較を行います。

文字列の比較は辞書式に基づいて行われます。

let stringD = "apple"
let stringE = "banana"

if stringD < stringE {
    print("stringDはstringEより辞書の前に来る")
}

このサンプルコードを実行すると、”stringDはstringEより辞書の前に来る”と表示されます。

なぜなら、「apple」は「banana」より辞書的な順序で前に来るためです。

○サンプルコード4:複数の条件を組み合わせる

複数の条件を組み合わせて比較する場合、論理演算子&&(AND)や||(OR)を使用することができます。

下記のサンプルコードは、複数の条件を組み合わせた比較を表しています。

let age = 25
let job = "engineer"

if age >= 20 && job == "engineer" {
    print("20歳以上でエンジニアの条件を満たしています")
}

if age < 20 || job == "student" {
    print("20歳未満、または学生の条件のいずれかを満たしています")
}

このコードの例では、ageが20以上かつjobが”engineer”であれば、”20歳以上でエンジニアの条件を満たしています”と表示されます。

また、ageが20未満もしくはjobが”student”であれば、”20歳未満、または学生の条件のいずれかを満たしています”と表示されます。

●Swiftの比較演算子の応用例

Swiftの比較演算子は、基本的な使い方だけでなく、さまざまな応用例でも利用されます。

今回は、条件分岐やループなどのプログラムの基本構造での使用例を中心に、比較演算子の応用方法を紹介します。

○サンプルコード5:条件分岐内での利用

比較演算子は、条件分岐の中でよく使用されます。

特定の条件を満たすかどうかを判断して、プログラムの処理の流れを変えることができます。

let score = 85

if score >= 90 {
    print("優秀")
} else if score >= 70 {
    print("良好")
} else {
    print("頑張りましょう")
}

このコードでは、変数scoreの値に応じて、異なるメッセージを出力します。

90以上であれば「優秀」、70以上であれば「良好」、それ以下であれば「頑張りましょう」と表示されます。

このサンプルを実行すると、「良好」と表示されることが確認できます。

○サンプルコード6:ループ内での使用

ループの中でも比較演算子を活用することができます。

特定の条件を満たすまでループを続けたり、条件に応じて処理を変えたりする場面で利用されます。

var sum = 0

for i in 1...100 {
    if i % 2 == 0 {
        sum += i
    }
}

print(sum)

このコードでは、1から100までの間で、偶数のみを合計する処理を行っています。

i % 2 == 0という条件は、iが偶数であるかどうかを判断しています。

このサンプルを実行すると、1から100までの偶数の合計である2550が出力されることが確認できます。

○サンプルコード7:関数やクロージャ内での使用

Swiftでは、関数やクロージャの中でも比較演算子を活用することが一般的です。

特に、関数の戻り値やクロージャの結果を決定する際に、比較演算子を使って条件分岐を行うことがよくあります。

□関数内での比較演算子の利用

関数の中で比較演算子を使う例として、2つの数値を受け取り、大きい方の数値を返す関数を考えてみましょう。

func maxNumber(a: Int, b: Int) -> Int {
    if a > b {
        return a
    } else {
        return b
    }
}

let result = maxNumber(a: 5, b: 8)
print(result)  // 8が出力されます。

このコードでは、maxNumber関数は2つの整数を引数として受け取り、大きい方の数値を戻り値として返します。

比較演算子>を用いて、どちらの数値が大きいかを判断しています。

□クロージャ内での比較演算子の利用

クロージャもまた、比較演算子を利用する場面があります。

例えば、配列のソートに使用されるクロージャでは、要素同士の比較を行う必要があります。

let numbers = [3, 1, 4, 1, 5, 9, 2, 6]
let sortedNumbers = numbers.sorted { $0 > $1 }
print(sortedNumbers)  // [9, 6, 5, 4, 3, 2, 1, 1] と降順にソートされて出力されます。

このコードでは、配列のsortedメソッドを使い、クロージャを引数として渡して配列をソートしています。

クロージャ内で比較演算子>を用いて、要素同士の大小関係を判断し、降順にソートされた新しい配列を生成しています。

○サンプルコード8:オブジェクトの属性を比較する

オブジェクト指向のプログラムでは、オブジェクトの属性同士を比較することも多いです。

例として、Personクラスのインスタンスを年齢でソートする場合を考えてみましょう。

class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

let people = [
    Person(name: "Taro", age: 25),
    Person(name: "Jiro", age: 20),
    Person(name: "Saburo", age: 28)
]

let sortedPeople = people.sorted { $0.age < $1.age }
for person in sortedPeople {
    print(person.name)  // Jiro, Taro, Saburo の順に名前が出力されます。
}

このコードでは、Personクラスの配列peopleを年齢で昇順にソートしています。

クロージャ内で比較演算子<を使用して、オブジェクトのage属性を比較し、ソートの基準としています。

○サンプルコード9:カスタム型での演算子のオーバーロード

Swiftでは、カスタム型に対しても比較演算子のオーバーロードが可能です。

これにより、独自のデータ構造やクラス、構造体での比較を自分のニーズに合わせてカスタマイズすることができます。

例として、Vectorという構造体を考えてみましょう。

この構造体は、2次元のベクトルを表現するもので、x成分とy成分を持っています。

このVectorの2つのインスタンスが等しいかどうかを判断する比較演算子をオーバーロードしてみます。

struct Vector {
    var x: Int
    var y: Int
}

extension Vector: Equatable {
    static func ==(lhs: Vector, rhs: Vector) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}

let v1 = Vector(x: 2, y: 3)
let v2 = Vector(x: 2, y: 3)
let v3 = Vector(x: 3, y: 2)

print(v1 == v2)  // true と出力されます
print(v1 == v3)  // false と出力されます

このコードでは、Vector構造体に対してEquatableプロトコルを採用し、==演算子をオーバーロードしています。

これにより、2つのVectorインスタンスがx成分とy成分の両方で一致している場合に等しいと判断されます。

○サンプルコード10:配列やコレクションの要素を比較する

Swiftの配列やコレクションの要素を比較する際も、比較演算子が頻繁に使用されます。

特に、.contains.filterなどの高階関数を使用する場合に、要素の条件を指定するために比較演算子が役立ちます。

例えば、特定の条件を満たす要素だけを抽出する場合を考えてみましょう。

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let evenNumbers = numbers.filter { $0 % 2 == 0 }

print(evenNumbers)  // [2, 4, 6, 8, 10] と偶数だけが出力されます

このコードでは、numbers配列の中から偶数だけを抽出するために、filterメソッドと比較演算子を組み合わせて使用しています。

$0 % 2 == 0の部分が、偶数である条件を表現しており、この条件を満たす要素だけが新しい配列evenNumbersに格納されます。

○サンプルコード11:Optional型との比較

SwiftにおけるOptional型は、変数が値を持つか、持たない(nil)かを表現するための特殊な型です。

比較演算子を使用してOptional型の値と非Optional型の値を比較する際には注意が必要です。

Optional型の変数が実際に値を持っているかどうかを確認するために、オプショナルバインディングやnil結合演算子を使うことが一般的です。

ここでは、Optional型のIntと非Optional型のIntを比較するサンプルコードを紹介します。

let optionalNumber: Int? = 5
let nonOptionalNumber: Int = 5

if let unwrappedNumber = optionalNumber, unwrappedNumber == nonOptionalNumber {
    print("両方の数値は同じです。")
} else {
    print("数値が異なるか、optionalNumberはnilです。")
}

このコードでは、オプショナルバインディングを使用してoptionalNumberが値を持っている場合にその値をunwrappedNumberに代入し、その後で非Optional型のnonOptionalNumberとの比較を行っています。

このようなアプローチを取ることで、安全にOptional型の値と非Optional型の値を比較することができます。

○サンプルコード12:タプルの比較

Swiftのタプルは、異なる型の値を一つのグループとして扱うことができるデータ構造です。

タプルの要素同士を比較する場合、比較演算子を直接使用することができます。

ただし、タプルの比較は、タプルの要素がEquatableプロトコルを採用している場合にのみ有効です。

以下は、2つのタプルを比較するサンプルコードです。

let tuple1 = (x: 1, y: 2)
let tuple2 = (x: 1, y: 2)
let tuple3 = (x: 2, y: 3)

if tuple1 == tuple2 {
    print("tuple1とtuple2は等しいです。")
}

if tuple1 != tuple3 {
    print("tuple1とtuple3は異なります。")
}

このコードを実行すると、tuple1tuple2が等しいこと、またtuple1tuple3が異なることを示すメッセージが表示されます。

このようにして、Swiftではタプル同士の簡単な比較が可能となっています。

●注意点と対処法

Swiftの比較演算子を効果的に使用するためには、いくつかの注意点や対処法を知っておくことが重要です。

○NaNや無限大の扱い

Swiftでは、浮動小数点数の計算の結果としてNaN(Not a Number)や無限大の値が生じる場合があります。

これらの特殊な値との比較は、通常の数値とは異なる挙動を示すことがあります。

例えば、NaNは自身との比較すらfalseと評価される特性があります。

let nanValue = Double.nan
if nanValue != nanValue {
    print("NaNは自身と等しくありません。")
}

このコードを実行すると「NaNは自身と等しくありません。」と表示されます。

このような挙動は、初心者にとっては直感的でない場合がありますので、NaNの扱いには注意が必要です。

また、無限大の値に関しても、正の無限大と負の無限大が存在し、これらの値は比較演算子を使って比較することができます。

let infinity = Double.infinity
let negativeInfinity = -Double.infinity

if infinity > negativeInfinity {
    print("正の無限大は負の無限大より大きいです。")
}

このコードを実行すると、「正の無限大は負の無限大より大きいです。」という結果が得られます。

○文字列比較時の大文字・小文字の区別

Swiftの文字列比較は、デフォルトで大文字と小文字を区別します。

しかし、場合によっては、大文字・小文字を区別せずに比較したい場面もあるでしょう。

その場合は、caseInsensitiveCompareメソッドやlocalizedCaseInsensitiveCompareメソッドを使用することで、大文字・小文字を区別せずに文字列の比較を行うことができます。

let string1 = "apple"
let string2 = "Apple"

if string1.caseInsensitiveCompare(string2) == .orderedSame {
    print("大文字・小文字を区別せず、string1とstring2は等しいです。")
}

このコードを実行すると、”大文字・小文字を区別せず、string1とstring2は等しいです。”と表示されます。

○等価性と同一性の違い

Swiftでは、オブジェクトの等価性(内容が同じであるか)と同一性(同じインスタンスを参照しているか)を区別することができます。

== 演算子は等価性を、=== 演算子は同一性をチェックします。

class SampleClass {
    var value: Int
    init(value: Int) {
        self.value = value
    }
}

let object1 = SampleClass(value: 10)
let object2 = SampleClass(value: 10)
let object3 = object1

if object1 === object3 {
    print("object1とobject3は同一のインスタンスを参照しています。")
}

if object1 !== object2 {
    print("object1とobject2は異なるインスタンスを参照しています。")
}

このコードを実行すると、「object1とobject3は同一のインスタンスを参照しています。」と「object1とobject2は異なるインスタンスを参照しています。」の2つのメッセージが表示されます。

●比較演算子のカスタマイズ方法

Swiftは非常に柔軟な言語であり、独自の型やクラスに対して比較演算子をカスタマイズすることが可能です。

特に、カスタム型やクラスを使用する際に、その型のインスタンス同士を比較したい場面が多々あります。

ここでは、カスタム型での比較演算子のカスタマイズ方法について詳しく解説します。

○カスタム型での比較演算子のオーバーロード

カスタム型やクラスで比較演算子を使用するためには、該当する演算子をオーバーロードする必要があります。

具体的には、比較演算子(==<など)の動作をカスタム型に合わせて定義します。

例として、Personという構造体を考えます。

この構造体はfirstNamelastNameという2つの文字列プロパティを持っています。

Person構造体の2つのインスタンスを==演算子で比較したい場合、次のようにオーバーロードを行います。

struct Person {
    var firstName: String
    var lastName: String
}

extension Person: Equatable {
    static func ==(lhs: Person, rhs: Person) -> Bool {
        return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName
    }
}

let person1 = Person(firstName: "Taro", lastName: "Tanaka")
let person2 = Person(firstName: "Taro", lastName: "Tanaka")
let person3 = Person(firstName: "Jiro", lastName: "Tanaka")

if person1 == person2 {
    print("person1とperson2は等しいです。")
}

if person1 != person3 {
    print("person1とperson3は異なります。")
}

このコードの中で、Equatableプロトコルを拡張して==演算子をオーバーロードしています。

このコードを実行すると、”person1とperson2は等しいです。”と”person1とperson3は異なります。”と表示されます。

このようにSwiftでは、カスタム型やクラスに対して比較演算子の動作を独自に定義することができます。

この機能を活用することで、より柔軟なコードの実装が可能となります。

まとめ

Swiftの比較演算子は、プログラムの制御フローを効果的に操作するための強力なツールです。

基本的な使い方から、カスタム型におけるオーバーロードまで、多岐にわたる利用方法が存在します。

初心者から上級者まで、それぞれのニーズに応じて比較演算子を適切に活用することで、コードの品質や効率を大きく向上させることができます。

本記事を通して、比較演算子の基本的な概念や、具体的な使い方、注意点、そしてカスタマイズ方法について詳しく解説しました。

Swiftを使用する上でのコーディングスキルや知識の向上に役立てていただければ幸いです。

今後もSwiftを学び続ける中で、比較演算子を始めとする各種の演算子や機能を適切に利用することで、より洗練されたプログラムの実装が可能となります。

継続的な学習と実践を通じて、Swiftの魅力を最大限に活かし、高品質なアプリケーションの開発を目指してください。