tetu式

ゲームと音楽・作曲の自己満足と悩みどころの多いプログラムのブログ。

XCode Swiftのタプル(Tuple)と配列(Array)の違い

今回はタプルと呼ばれるものについて。

タプルっていうのはSwiftの中では複数の値を一つにまとめた変数のことを言います。
これだけ聞くと配列でいいんじゃね?って思うんですけども、どうなんでしょ?
配列のことについてもまだこのブログ内で触れていないので合わせてやってみます。




まずはタプルの宣言と使用方について。

var tpl = (123, "一二三", "ひふみ", 456)

print(tpl.0)  // 123
print(tpl.1)  // 一二三
print(tpl.2)  // ひふみ
print(tpl.3)  // 456

print(tpl.0 + tpl.3)  // 579

値を取り出す時は、変数名の後ろにドットと数字を入れて取り出します。
型を省略していますが

var tpl :(Int, String, String, Int) = (123, "一二三", "ひふみ", 456)

こういう書き方と同じ意味です。

対してSwiftの配列というのは

var arr :[Int] = [123, 456, 789]

print(arr[0])  // 123
print(arr[1])  // 456
print(arr[2])  // 789

print(arr[0] + arr[1] + arr[2])  // 1368


こう書きます。
PHPは配列の初期値入力に{ , }を使いますがSwiftは[ , ]なんですね。
値の取り出しは変数名の後ろに[数字]。
書き方は違いますが値の取り出し方は似てますね。


ここで一点、タプルと配列で違うこと。
タプルの中に入っている値の型はInt, String, String, Floatとなっていますが、
配列は型宣言している通り、全てIntです。


次の違いは値の変更や追加について。
こちらは配列の例を先に見ます。

var arr :[Int] = [123, 456, 789]

print(arr[0])  // 123
print(arr[1])  // 456
print(arr[2])  // 789
print(arr.count)  // 配列長:3

// 値の変更
arr[0] = 234
print(arr[0])  // 234

// 値の追加
arr.append(1000)
print(arr[3])  // 1000
print(arr.count)  // 配列長:4

// 別の同型変数からの代入
var arr2 :[Int] = [123, 234, 345, 456, 567]
arr = arr2
print(arr[0])  // 123
print(arr[1])  // 234
print(arr[2])  // 345
print(arr[3])  // 456
print(arr[4])  // 567
print(arr.count)  // 配列長:5


配列の特徴として値の変更はともかく、変数の長さが可変するという点があります。

それに対し、タプルは最初に初期値を決定した時にそういう型として固定されます。

var tpl = (123, "一二三", "ひふみ", 456)

print(tpl.0)
print(tpl.1)
print(tpl.2)
print(tpl.3)

print(tpl.0 + tpl.3)

// 値の変更
tpl.0 = 234
print(tpl.0)  // 234

tpl = (123, "一二三", 666, 789)  // 3番目がStringでないのでエラー

tpl = (123, "一二三", "ひふみ", 456, 789)  // 値の個数が違うのでエラー


違いの2点目としては配列と違って可変長ではないことです。

そしてもう一つ。数字で位置を指定して値を取り出しているので
繰り返し処理できそうですができません。

var tpl = (123, 234, 345, 456, 567)
var arr :[Int] = [123, 234, 345, 456, 567]


for (var i=0; i<arr.count; i++) {
    print(arr[i])  // arrの中身を頭から順にprint
    print(tpl.i)  // エラー
}

配列の場合、[]内に入れるのは本当の意味での数字、順番という感じですが
タプルの場合のドットに後ろの数字は名前という意味合いが強いと思います。

ということで実際にタプルの内容には名前をつけてあげることができます。

var tpl = (numA:123, strA:"一二三", strB:"四五六", numB:456)

print(tpl.numA)  // 123
print(tpl.numB)  // 456
print(tpl.strA)  // 一二三
print(tpl.strB)  // 四五六


こんなところでしょうか。
その場で使えるインスタント構造体みたいな感じですかね。


おまけ。

func mixprint(tplA: (Int, String, String, Int)) {
    print(tplA.0)
    print(tplA.1)
    print(tplA.2)
    print(tplA.3)
}

var tpl = (numA:123, strA:"一二三", strB:"四五六", numB:456)
mixprint(tpl)

関数の引数としてもタプルは使えます。
呼び出す時に引数がひとまとまりになるのでそこは良いのですが
実装部分はちょっとごちゃっとしますね・・・

まぁ今回はタプルの中身が適当だからかもしれませんが、
しっかり名前付けしてあげることで宣言や実装が面倒になる反面、
見やすい内容になるかと思います。