LoginSignup
4
3

More than 3 years have passed since last update.

【Swift】compareについて考えてみた

Posted at

これは初学者である筆者が初めてcompareと出会った時の思考を綴るものとなっております。

ここでいうcompareはSwiftのStringクラスインスタンスメソッドcompareを指します。

compareの返り値って何なの問題

ComparisonResultですね。はい、おしまい。

・・・とならないのが初学者です。
私ももれなくその一人でした。
AppleDeveloperドキュメントにも、目立つくらいReturn Valueって書いてあるのに!

そんな初歩的なところでつまづいている訳ですが、試行錯誤の過程は良い勉強になったのでこちらにアウトプットという形で残すことにしました。

どこで出会ったのか?

Swift実践入門 第3版 P53
Foundationによる高度な操作 見本コードにて

上記箇所となります。
swiftの学習にと、こちらの書籍を手に取る初学者の方も多いのではないでしょうか。
私は上記箇所で突然現れた次のコードをみて固まってしまいました。

// P53 見本コード
import Foundation // compareはFoundationというライブラリで提供されているメソッド

// 2つの文字列間の順序の比較
let options = String.CompareOptions.caseInsensitive
let order = "abc".compare("ABC", options: options)
order == ComparisonResult.orderedSame //true

上記のコードでは、compare(_:option)メソッドで2つの文字列間の順序を検証しています。
--略-- 結果として順序が同じであることを意味する.orderSameという値を得ています。

一読しただけではよく分かりませぬ。

コードリーディングしてみる

まず1行目

let options = String.CompareOptions.caseInsensitive

これはConpareメソッドに用意されているオプションで、大文字と小文字を区別しないというもの。
これを定数optionsとして定義している。

2行目

let order = "abc".compare("ABC", options: options)

右辺では、文字列"abc"に対してcompareメソッドを使用し()内の"ABC"との比較をしている。その際、引数として先ほど定義したoptionsを受け取っている。
ここで得られた結果を、定数orderとして定義している。

3行目

order == ComparisonResult.orderedSame

2行目で定義したorderComparisonResult.orderedSameを比較演算子にかけ、trueが返ってくる。

細かな内容について考えてみる

上記を踏まえ少しコードを簡素にした。
オプションについては疑問点とは関係なさそうなので省略。

let order = "abc".compare("abc")
order == ComparisonResult.orderedSame // true

つまり、"abc".compare("abc")の返り値はComparisonResult.orderedSameということ?

確認してみた。

let hoge = "abc".compare("abc")
print(hoge) // NSComparisonResult

実行結果・・・NSComparisonResult

ComparisonResultとは

見本コードでも何食わぬ顔で現れたこいつを理解する必要がありそう。

ComparisonResult

調べてみるとComparisonResult列挙型で、3つのcase定数を持つということが分かった。

enum ComparisonResult: Int {
    case orderedAscending = -1
    case orderedSame = 0
    case orderedDescending = 1
}

ということはcompareメソッドはcaseのどれかを取得した後、ComparisonResultを返すということになると考えられる。

  • case orderedAscending ・・・ <
  • case orderedSame ・・・ =
  • case orderedDescending ・・・ >

今回は比較対象がイコールであったため、orderedSameという値を取得し、
ComparisonResult.orderedSameが返されたということになります。

compareの返り値

ということで冒頭のコードに戻ってみる。
せっかくなので、"ABC"だったところを"DEF"に変えてみる。

let options = String.CompareOptions.caseInsensitive
let order = "abc".compare("DEF", options: options)
order == ComparisonResult.orderedAscending
// true

2行目の"abc".compare("DEF", options: options)の返り値がComparisonResult.orderedAscendingなのでtrueということとなる。
abc < DEFという比較結果となっています。

後語り

今、自分で書いていても、「なぜこんなことが気になったのだろう?」と感じてしまうような内容ですね・・・

思いつく理由としては、メソッドの返り値が列挙型ということに戸惑いがあったからなのかもしれません。

別のメソッドですが、以下のようなシンプルな挙動をイメージしていました。
私が期待していたようなコード及び実行結果

// 私が期待していたようなコード及び実行結果
"abc".isEqual("abc")
// true

今回も上記のような形が頭から離れず「比較系メソッドはtrue/falseが返り値となるものだ」という先入観により、つまづき理解に苦しんでしまいました。

結論:さっさと公式ドキュメント読めばよかった。

おしまい。

ここまでお読みくださりありがとうございましたm(__)m

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3