SwiftのTuples

SwiftのTuples

Tupleです。発音はタプルと書かれていることが多いですが、英語では”two-pull”(トゥープル)と呼ぶ場合もあります。私は後者の方が馴染みがありますが、日本語で書くと混乱しそうですので、ここでは英語のTupleを使います。Tupleは、ものすごく単純化すると「なんでも入るコレクション型」のようなものです。後で紹介しますが、Swiftの基本型はなんでも入ります。コレクション型の基本を学習した後の方が、tupleを理解しやすいかもしれません。

Tupleは色々なところに顔を出すので、是非理解しておきたいですね。

SwiftのTuple

Tupleの初期化

Tupleは、おおざっぱに言うと、どんな型でも入れられるコレクション型です。Tupleを初期化する際には

// Tupleの初期化
let constantTuple = (value1, value2, ...)

という具合に、値value1をコンマ,で区切り、全体をカッコ()で囲みます。配列リテラル[...]のカッコを丸括弧に変更したようなイメージです。ここでは定数を例としましたが、変数のtupleも宣言できます。

実際にやってみましょう

// Tupleの使用例
let someTuple = (2015, 3.14, "hello world!", true)

このようにあらゆる基本型を入れることができます。

Tuple要素へのアクセス

添字(index)でアクセス

Tupleの各要素へアクセスする場合には、

// 要素へアクセス
print("\(someTuple.1)")
// "3.14"と表示

のように、tupleとして宣言した定数(変数)の後ろにピリオドと数字を付けます。数字はコレクション型と同様に0から始まりますので、最初の要素を指定したい場合はsomeTuple.0とします。

別の定数(変数)に代入して取り出す

各要素へ名前をつけて(各要素を定数・変数化)取り出すこともできます。

// 要素を名前をつけて取り出す
let (twentyFifteen, pi, hello, someBoolean) = someTuple
print(hello)
// "hello world!"と表示

このように、各要素に名前をつけると、添字指定ではなく名前でアクセスすることができるようになります。

ある特定の要素だけを取り出したい場合は、

// 特定の要素だけを取り出す
let (twentyFifteen, _, _, _) = someTuple
// または要素を定数に代入
let twentyFifteen = someTuple.0

のようにして、個々の要素にアクセスできます。要素数が多い場合は、後者の書き方が便利かもしれません。

初期化の際に名前を付ける

初期化する段階で、各要素に名前をつけることもできます。

// 初期化の際に名前をつける
let someTuple = (twentyFifteen:2015, pi:3.14, hello:"hello world!", someBoolean:true)

// tuple名.要素の名前でアクセス
if someTuple.someBoolean {
    print("pi = \(someTuple.pi)")
}

これは辞書リテラルに似ていますね。

Tuple要素の変更

要素を変更する場合は、変更したい要素を添え字で指定して、そこに値を代入すれば可能です。

// 要素の変更
var someTuple = (2015, 3.14, "hello world!", true)
print("\(someTuple.0)") // 2015
someTuple.0 = 2014
print("\(someTuple.0)") // 2014

Tupleの使いドコロ

関数の戻り値(複数の戻り値を持つ関数の場合)

公式マニュアルに書いてありますが、tupleの有効な使いドコロの一つに、関数の戻り値があります(参考:「The Swift Programming Language, Tuples」)。Tupleのような機能がない場合、関数の戻り値に複数の型(値)を持たせるには、構造体などを使用しなければならないので手間がかかります。しかし、tupleを利用すると、複数の型を持った戻り値を簡単に実装できるというわけです。

Dictionary要素をfor-in文で取り出す際の一時変数

Dictionaryコレクション型はkey, valueペアで一組の連想配列ですから、要素を取り出す場合、これら1組を入れる一時変数が必要です。Tupleとfor-inを使って、Dictionary要素のペアを一度に取り出すことが可能です。

// Dictionary要素を取り出す
let theme = ["twentyFourteen": 2014, "twentyFifteen": 2015]
for (name, year) in theme {
    print("テーマ:\(name), 年:\(year)")
}
//テーマ:twentyFifteen, 年:2015
//テーマ:twentyFourteen, 年:2014

補足:
公式マニュアルの注意書きによると、tupleは一時的な値の集合としての使用や、単純な値のグループ分け(関数の戻り値など)には適しています。しかし、複雑な構造を持った値のグループ分けをする場合には、構造体(structure)やクラス(class)を用いるべき、とのことです。


まとめ

  • Tupleは、どんな型でも入るコレクション型、のようなもの
  • Tupleのn番目の要素はtuple.nでアクセス可能
  • Tupleの要素に任意で名前を付ける(定数・変数化)ことができる