Swiftの比較演算子と範囲演算子(Comparison, Range Operators)

比較演算子と範囲演算子

ここでは、比較演算子と範囲演算子に関して、基本的な使い方を紹介します。比較演算子は名前通りの演算子で、値の比較をしてその結果をブール値で返す演算子です。これは直感的に理解しやすいのではないかと思います。範囲演算子は少し特殊な演算子で、用途は繰り返し処理などに限定されますが、便利な演算子です。

比較演算子(comparison operator)

比較演算子は6種類

比較演算子はその名前の通り、値同士の比較をするoperatorです。6つ演算子があって、まとめると以下のようになります。

演算子 文章による表現 使用例
a == b aとbは等しい a == 1
a != b aとbは等しくない a != 2
a > b aはbより大きい a > 3
a < b aはbより小さい a < 4
a >= b aはb以上 a >= 5
a <= b aはb以下 a <= 6

上記の文章による表現では誤解を招きそうなので、正しく説明すると、a==bというのは「aとbが等しいかどうか」を判定する演算です。その比較結果を戻り値としてBooltrue, false)で返します。

比較演算子を使う簡単なサンプルコード

実際の例で見てみましょう。

var a = 2
var b = 3
a == b // falseを返す。2と3は等しくない
a != b // trueを返す。2と3は等しくない
a > b  // falseを返す。2は3より小さい
a < b  // trueを返す。3は2より大きい
a >= b // falseを返す。
a <= b // trueを返す。
// 直接値同士の比較も可能です
2 > 3  // false

上記の例では整数同士を比較しましたが、Double同士やString同士の比較もできます。

// Doubleの比較
var c = 3.14
var d = 3.05
c == d // false
c != d // true
...
// Stringの比較
var e = "hello"
var f = "2015"
e == f // false
e != f // true
e > f  // true。文字列の"大小"も比較できる

実は文字列の比較にも>, <, >=, <=が使えるのを確認してびっくりしたんですが、どうやら文字に割り振られているUnicodeを使って大小を比較しているようです。

もちろんBool同士の比較もできます。ただし大小比較はできません。

// Boolの比較
true == false // false
true != false // true
true > false  // コンパイルエラー

他の演算子と同様に、異なる型の比較はできませんので、型変換して比較する必要があります。

// IntとDoubleの比較
a == c      // コンパイルエラー
a == Int(c) // false。型変換すれば通る

比較演算子は特にループ(for-in文while文)、条件分岐(if文など)を使用する時に重要になります。

// if文で使う比較演算子の例
if e == f {
  print("同じ文字列です: \(e)")
}
else{
  print("違う文字列です: \(e), \(f)")
}
// "違う文字列です: hello, 2015"と表示

Tuplesの比較も出来る

同じ要素数のtuplesは比較が出来ます。Swift 2.2から追加された機能かどうかは分かりませんが、公式ドキュメントには追加されています。Tuples比較のルールとしては、

  • 個々の要素が比較可能であれば、全体のtupleも比較可能
  • Tuplesの比較は左から右へ、かつ要素ごとに実行
  • 要素の比較は、異なる2つの要素が見つかるまで続行
  • 全ての要素が同じなら、tuples自体も同じ

ということのようです。したがって、例えばIntStringで構成されたtuple同士の比較は可能です。一方で、Bool型を含むtupleの比較は出来ないようです。

試してみましょう。

// tuplesの比較
(1,1) < (2,1) // true
(1,1) < (1,0) // false
(2, "hello") < (2, "world") // true

// Boolが入っているとダメ
(true, 1) < (false, 5)
// error: binary operator '<' cannot be applied to two '(Bool, Int)' operands

最初の例では、一番最初の要素比較1 < 2trueが決まっています。2番目の例では、最初の要素は同じなので、判定は2つ目の要素同士の比較1 < 0falseです。3番目の結果も、基本は2番目と同じです(1つ目の要素は同じなので、2つ目の要素で判定)。

公式マニュアルによると、tuplesの比較演算子は7個未満の要素を持ったtuplesまでは対応しているようです。それ以上の要素を持ったtuplesを比較する場合は、自分で比較演算子を実装しないといけないようですね。

“NOTE

The Swift standard library includes tuple comparison operators for tuples with less than seven elements. To compare tuples with seven or more elements, you must implement the comparison operators yourself.

抜粋:: Apple Inc. “The Swift Programming Language (Swift 2.2)”。 iBooks https://itun.es/jp/jEUH0.l

範囲演算子(range operator)

範囲演算子って何?

範囲演算子は2つあり、値の範囲を示す演算子です。

  • Closed range operator a...b: aとbを含む数値範囲 (a <= x <= b)
  • Half-open range operator a..<b: aのみを含む数値範囲 (a <= x < b)

Half-open range operator a..<bは、例えば1..<4の場合、1,2,3を表します(最後の4は含まない)。またa, bは整数で、かつa<=bという条件を満たしてないといけません。

範囲演算子の具体例 | 繰り返し処理での使用

演算子自体の見た目でも分かりやすいですが、実際に試してみましょう。範囲演算子は繰り返し処理(forなど)の際に使えそうですね。

// Closed range operatorの使用例
for index in 0...5 {
  print("indexは\(index)です")
}
// 結果:
//indexは0です
//indexは1です
//indexは2です
//indexは3です
//indexは4です
//indexは5です

// Half-open range operatorの使用例
for index in 0..<5 {
    print("indexは\(index)です")
}
// 結果:
//indexは0です
//indexは1です
//indexは2です
//indexは3です
//indexは4です

上記の例のように、closed range operatorでは0から5まで表示されていますが、half-open range operatorでは最後の5が表示されていません。

感のいい人は気づいたと思いますが、範囲演算子は負の値を指定しても、a<=bという条件を満たす限り問題ありません。

// 負の値を指定
for index in -5...(-2) {
  print("indexは\(index)です")
}
// 結果:
//indexは-5です
//indexは-4です
//indexは-3です
//indexは-2です

ただし、後ろの数字をカッコ()で囲まないとコンパイルエラーになります

数字を変数で置き換えた場合はカッコで囲まなくても大丈夫でした。

まとめ

  • 比較演算子では異なる型の比較はできない。例)IntDouble
  • Stringの大小比較もできる(文字に割り当てられているUnicodeで比較)
  • 範囲演算子は(1)終端を含むa...bと(2)終端を含まないa..<bがある