2017-01-25 11 views
0

ここで状況[のジェネリック版]です:Swift:変数/引数を使用してタプル要素にアクセスしますか?

let tuple: (first: Int, second: Int, third: Int) // tuple.0 is equivalent to tuple.first 

enum TupleIndex: Int { 
    case first = 0, second, third 
} 

func selectTupleElement (index: TupleIndex) { 
    let indexNum = index.rawValue 
    let tupleElement = tuple.indexNum // Oh noooooo!!! 
} 

はコンパイラがないもちろんこれ(「tupleindexNumプロパティまたは要素」として、上記の最後の行に示されている、問題のスポットを読み込み"indexNumの値に等しいtupleの要素"というよりも)

タプルを使用して何をしようとしているのですか?

+0

私は道を考えた: 'arrayInstead = [INTは()' –

+2

なぜ配列を使用しないようにしましょうか?タプルを使用する利点は何ですか? – Sweeper

+0

@ Sweeper、私はタプルを使いたいので、配列に必要な数値インデックスではなく要素に名前を付け、その名前インデックスで要素を参照することができます。しかし、私は、インデックス番号に等しい変数を作成することであるソリューションを、考え出したし、私は
は最初の '= 1 '
'てみましょうindexNum = first'
'聞かせて選択=配列[indexNumを聞かせて言うことができます] '


しかし、それはタプルで行うことができる場合私は興味があります。ちょっと興味があるんだけど! –

答えて

0

あなたランタイムのイントロスペクションの使用が条件付きで抽出するために作ることができn:番目の組の固定サイズ、同じ型のメンバーののメンバー(例えば以下:制服とアリティ3のタプルのために実装がメンバーを入力)し、 (条件付きで)メンバーの型に変換します。例えば:

func selectTupleElementFor<T>(memberNumber: Int, inTuple tuple: (T, T, T)) -> T? { 
    return Mirror(reflecting: tuple).children.enumerated() 
     .first(where: { $0.0 == memberNumber - 1 }).flatMap { $1.1 as? T } 
} 

// example usage 
let tuple: (first: Int, second: Int, third: Int) = (10, 20, 30) 
if let tupleMember = selectTupleElementFor(memberNumber: 2, inTuple: tuple) { 
    print(tupleMember) // 20 
} 

または、使用してTupleIndexenum

enum TupleIndex: Int { 
    case first = 0, second, third 
} 

func selectTupleElementFor<T>(tupleIndex: TupleIndex, inTuple tuple: (T, T, T)) -> T? { 
    return Mirror(reflecting: tuple).children.enumerated() 
     .first(where: { $0.0 == tupleIndex.rawValue }).flatMap { $1.1 as? T } 
} 

// example usage 
let tuple: (first: Int, second: Int, third: Int) = (10, 20, 30) 
if let tupleMember = selectTupleElementFor(tupleIndex: .second, inTuple: tuple) { 
    print(tupleMember) // 20 
} 
+0

...そして、私は提案されたdupeターゲットが、自分自身で書かれた同様のイントロスペクションアプローチの解決策を含んでいることに気づきました.DH xDとにかく、OPs自身の 'TupleIndex'タイプを使用している例を示します。イントロスペクションの実装は、デュープターゲットの(受け入れられない)アンサーとは少し異なります。 – dfri

+0

この例では、 'enumerated()'と 'first(where:)'を使うよりも、 '子ども自身のインデックスを進めること(他の答えなど)が良いアプローチだと思います。ランダムアクセスコレクションのためのO(1)インデックスの利点ですが、後者は(ミラーではしばしば動作しませんが、どのような状況でそれが 'ランダムにアクセス可能であるかどうかはわかりますか?:)) – Hamish

+0

@Hamish 'children'呼び出しは、タイプが消去されたコレクションラッパー[' AnyCollection'](https://developer.apple.com/reference/swift/anycollection)を返します。 - 収集されたコレクションです)。タイプ消去されたコレクションラッパー['AnyRandomAccessCollection'](https://developer.apple.com/reference/swift/anyrandomaccesscollection)と比較してください。とにかく、私たちはタプル(固定アリティを静的に指定する関数を使って)を使ってイントロスペクションを行っているので、ランダムアクセスと 'O(n)'トラバーサルがここで問題になるとは思わない... – dfri

関連する問題