LoginSignup
11
8

More than 5 years have passed since last update.

Swift で Tuple より Array を生成する方法

Last updated at Posted at 2016-02-10

Tuple から Array を使いたい場面に遭遇しました。ざっくり言うと以下のようなイメージです。

let tuple = (1, 2, 3, 4)
let array = // 変換
print("\(array)") // [1, 2, 3, 4]

ググってみると熊谷さんのページ *1 にヒットしましたが、Swift の互換性の問題かビルドエラーになってしまいます。このまま頑張ってみる手もあるかもしれませんが、tuple を let でなく var で用意しないといけないところや、count をハードコードしなくてはいけないところが少し残念に思ったので、他の方法を考えてみる事にしました。

var tuple = (1, 2, 3, 4) // 'var'
let buffer = UnsafeBufferPointer(start: &tuple, count: 4)
let array = Array<Int>(buffer) // error

試行錯誤の末に、以下のような関数にたどり着きました。

arrayFromTuple.swift
func arrayFromTuple<T, U>(tuple: T) -> [U] {
    return Mirror(reflecting: tuple).children.map { $0.value as! U }
}

簡単に説明すると tuple を Mirror に食わせてあげると、各タプルの要素を拾うことができるので、これを map で配列に作り直してあげます。 as! U を使っているので、想定外の型の値が紛れ込むと落ちますので、ご注意ください。

これを以下のように使えば…と言いたいところですが、これではエラーになってしまいます。 U の型が決定していないからです。

let tuple = (1, 2, 3, 4)
let array = arrayFromTuple(tuple) // error

そこで 以下のいずれかの書き方をすれば、U の型が決定するのでビルド可能となります。タプルの型さえ揃っていれば、いくつ連続していても構いません。

let tuple = (1, 2, 3, 4)
let array1 = arrayFromTuple(tuple) as [Int] // [1, 2, 3, 4]
let array2: [Int] = arrayFromTuple(tuple)   // [1, 2, 3, 4]

一応、将来の Swift の互換性の問題があるかもしれないので、この記事の執筆の時点の Swift のバージョンを記しておきます。

$ swift --version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.3.0

*1 Swift でタプルを配列に変換する
https://ez-net.jp/article/D9/m3Nv4a1J/tJo7H-D4ydQ2/

11
8
2

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
11
8