Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. Swift入門編 - タプル(tuple)について

タプル(tuple)について

みなさまどうも。

さて、続きまして『タプル』(tuple)についてやっていきましょう。『タプル』も配列や辞書と同じようにいくつかの値とかをひとまとめにしたものになります。

そんでもって、「配列や辞書と何が違うの?」ってお話なんですが、Swiftの配列や辞書はデータ型に非常に厳格で基本的に同じデータ型しか入らないので「データ型の違う複数の値を一時的に保存しておきたい」というような場合になると色々と面倒くさいんですよね。

データ型の違う値を配列とか辞書で保存するとなるとAny型とかAnyObject型なんかを使用することになるのですが、そうするとその値を使用するときに毎回型変換(キャスト)しないと演算ができなかったりします。

しかし『タプル』を使用すればそのままのデータ型で保存できる、つまり各値を使用するときとかにいちいち型変換をしなくてもそのままの形で演算できるので状況によっては非常に強力です。

というわけでやっていきましょう。『タプル』を定義するにはまず『()』を記述し、そのなかに値を入れたりすればOKです。こんな感じですね。

let t = ("初音ミク", 100, 0.5) // 『タプル』を定義します。

print(t) // 『("初音ミク", 100, 0.5)』と出力されます。

『タプル』の中に配列とか辞書を入れることもできます。その場合は以下のようにインデントしてあげると読みやすいかもです。この辺はお好みでどうぞ。

let t = ( // 配列とか辞書も入れられます。こんな風にインデントしてあげると読みやすいかもしれません。
    [0, 1, 2],
    ["初音ミク": "080-xxxx-yyyy"]
)

print(t) // 『([0, 1, 2], ["初音ミク": "080-xxxx-yyyy"])』と出力されます。

これらのサンプルのように「あたし、キミが望むならどんなデータ型でも入っちゃうから...///」ってところも注目しておいて下さい。これが『タプル』ちゃんの便利なところになります。

そんでもって変数や定数に代入せずにそのまま記述することもできちゃいます。以下は『print()』の『()』の中に『タプル』を直接記述したパターンですね。

print(("初音ミク", 100, 0.5)) // 『("初音ミク", 100, 0.5)』と出力されます。

こんな感じでとりあえず定義するだけならめっちゃ簡単です。

続いて『タプル』の中の各値にアクセスする方法を確認していきましょう。以下のサンプルをちょいとみてみてください。

let t = ("初音ミク", 100, 0.5) // 『タプル』を定義します。

定数『t』のタプルの中身は『初音ミク』、『100』、『0.5』になってますね。この各値にアクセスするには『t.0』、『t.1』といったように『タプル名.番号』と記述すればOKです。配列と似たような感じですね。こんな感じになります。

let t = ("初音ミク", 100, 0.5) // 『タプル』を定義します。

print(t.0) // 『初音ミク』が出力されます。

ちょっと注意点ですが、配列と同じように『1番目』からでなく『0番目』から数え始めるので間違えないようにして下さいね。

ちなみに『タプル』の中に配列が入っていた場合のアクセス方法はこんな感じです。

let t = ("初音ミク", [0, 1, 2])

print(t.1[0]) // 『0』が出力されます。

『タプル名.番号[配列のインデックス]』って感じの記述になりますね。数値だらけでごちゃごちゃしちゃってますがそこは気合でがんばってください。

さて、続きまして『タプル』には『ラベル』を付けることもできますのでそれも確認していきましょう。『タプル』に『ラベル』を付けるにはこのような感じになります。

let t = (name: "初音ミク", tellNum: "080-xxxx-yyyy")

print(t) // 『("初音ミク", "080-xxxx-yyyy")』と出力されます。

上記の『(name: "初音ミク", tellNum: "080-xxxx-yyyy")』のように『ラベル名: 値』という感じで記述すればOKです。

そして各値にアクセスするには以下のようにします。以下はタプル『t』の『name』を出力している感じですね。

let t = (name: "初音ミク", tellNum: "080-xxxx-yyyy")

print(t.name) // 『"初音ミク"』と出力されます。

上記のように『タプル名.ラベル名』とすればその値にアクセスすることができます。先程は『タプル名.番号』だったんで配列っぽい記述でしたが、今度は辞書っぽい感じの記述でアクセスできていますね。

そしてちょっと注意点ですが、『ラベル』を付けた『タプル』は番号でもアクセスすることができます。こんな感じですね。

let t = (name: "初音ミク", tellNum: "080-xxxx-yyyy")

// 以下はどちらでもOKです。
print(t.0) // 『"初音ミク"』と出力されます。
print(t.name) // 『"初音ミク"』と出力されます。

なので「『タプル』の『ラベル』はオプション」、といったイメージになりますね。『ラベル』を付けた『タプル』は番号でしかアクセスすることはできない、というわけではないのでご注意です。

そしてもういっちょ注意点です。「そうだ、『タプル』を定義しよう!」と思った時に『()』の中に複数の値とかを記述してくわけなんですが、『()』中に要素を1つだけしか記述しなかった場合は『タプル』扱いされません。以下のサンプルを見てみてください。

let t = ("初音ミク")

上記の定数『t』は『タプル』である、と思って以下のような記述をするとエラーです。

let t = ("初音ミク")

print(t.0) // エラーです。

上記の定数『t』の代入式『("初音ミク")』の『()』は算術の優先順位を決める『()』の扱いになっちゃいます。数学の『(1 + 3) ✕ 3』とかで優先順位を決めるときに使用する『()』ですね。

なので上記の場合は『タプル』扱いされず、『初音ミク』を出力させるならばこうなります。

let t = ("初音ミク")

print(t) // 『初音ミク』が出力されます。

ただ『t』と記述してるだけでアクセスできちゃってますね。

そんでもって『タプル』扱いじゃないわけなので以下のように『ラベル』を付けたらエラーになっちゃいます。

let t = (name: "初音ミク")

print(t.name) // エラーです。

このように『タプル』を定義する際は2つ以上の要素を入れる必要がありますので間違えないように気をつけて下さい。

さて、では続きまして『タプル』の応用技をちょっと紹介しておきます。

実は変数とか定数の定義の際に『タプル』を使うことで、それぞれの値を変数とか定数に代入することができます。ちょっと言葉にするとややこしいので以下のサンプルを確認してみましょう。

let (n, s) = (1, "初音ミク")

print(n) // 『1』が出力されます。
print(s) // 『初音ミク』が出力されます。

上記の『(n, s) = (1, "初音ミク")』ってところに注目です。『let』なので定数を定義しているわけなんですが、左辺に『(n, s)』、右辺に『(1, "初音ミク")』となっていますね。これで定数『n』に『1』が、定数『s』には『初音ミク』が代入されます。

つまり、以下と同じ結果になるということです。

// 上記のサンプルはこれと同じ結果になります。
let n = 1, s = "初音ミク"

print(n) // 『1』が出力されます。
print(s) // 『初音ミク』が出力されます。

そんでもって、『let (n, s) = (1, "初音ミク")』と記述する場合と『let n = 1, s = "初音ミク"』と記述する場合で何が違うのか、ってお話なんですがちょいと前回の記事の最後の方で紹介したサンプルを思い出してみましょう。以下のやつですね。

func test(n: Int, s: String) -> (Int, String) {
    return (n, s)
}

let tpl = test(n: 10, s: "初音ミク")

print(tpl) // 『(10, "初音ミク")』と出力されます。

上記のサンプルの関数『test』は『-> (Int, String)』とあるようにInt型とString型を『タプル』で返す処理になってますね。それを定数『tpl』でまとめて受け止めてる形です。

しかし、状況によっては「関数から『return』された『タプル』をそれぞれ違う定数とか変数とかで受け止めたいぜぇ」というロマンチックな気分になる時があるかと思います。

そういう時に先程の記法を使ってみましょう。こんな感じですね。

func test(n: Int, s: String) -> (Int, String){
    return (n, s)
}

let (num, str) = test(n: 10, s: "初音ミク") // 戻り値をそれぞれの定数で受け止めます。

print(num) // 『10』と出力されます。
print(str) // 『初音ミク』と出力されます。

この記法、結構強力なんで覚えておいて下さい。

『タプル』を使って変数とか定数とかに代入する際に「一部の値を無視した状態で代入したい」といった場合には『_』を使ってみましょう。以下のサンプルを見て下さい。

let (_, n, _, s) = (1, 2, 3, "初音ミク")

print(n) // 『2』が出力されます。
print(s) // 『初音ミク』が出力されます。

上記のサンプルのタプル『(1, 2, 3, "初音ミク")』の0番目の要素と2番目の要素を飛ばした状態で代入できていますね。

このように無視したいところに『_』を記述することでその要素をシカトした代入処理が行うことができます。

これも結構便利なので使ってみて下さい。

というわけで『タプル』について以上になります。続いての記事では関数の『オーバーロード』についてやっていきましょう。

ではではこの辺で。失礼致します。

この記事は桜舞が執筆致しました。

著者が愛する小型哺乳類

桜舞 春人 Sakurama Haruto

ISDN時代から様々なコンテンツを制作しているちょっと髪の毛が心配な東京在住のプログラマー。生粋のロングスリーパーで、10時間以上睡眠を取らないと基本的に体調が悪い。好きなだけ寝れる生活を送るのが夢。ゲームとスポーツと音楽が大好き。誰か髪の毛を分けて下さい。

記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。