2016-08-07 15 views
1

私は自分のコードを最適化しようとしています。私は次のことをしたい:dictの要素がfirstNamesの配列にある場合は、この要素をfirst変数に直接書き込むことができます。これはsecondなどと同じです。また、私は、ループを反復処理するとfirstに値を設定しようとしsecondvalString Swiftと同じ名前の変数の使用方法

を使用しています> secondとなど - > firstsecondNames < - 私は、変数 firstNames <をリンク含ま names配列を作成しました
let dict = ["type": "1", "word": "abc"] // this is example 
    let firstNames = ["1", "2"] 
    let secondNames = ["3", "4"] 
    var first = String() 
    var second = String() 
    let names = [firstNames: first, secondNames: second] 
    for el in dict { 
     for var (key, val) in names { 
      if (key as! [String]).contains(el["type"]!) { 
       if ((val as! String) != "") { 
        val = (val as! String) + ", " + el["word"]! 
       } 
       else { 
        val = el["word"]! 
       } 
      } 
     } 
    } 

このコードには実行時エラーがありません。しかし、残念ながら私がループにvalを設定しようとしているときに何も起こっていません。私が間違ってやっているのはもっと洗練された解決策ですか?

ありがとうございました。

+2

私は、あなたがしたいことを正確に完全には追い抜いていません。 'dict'のようなものの例を追加できますか?現在、 'names'変数はarrayという名前の辞書であり、valueはstring(' [[String]、String] ')です。 –

+0

@PaulPeelenが追加されました。私は変数 '1abc'を持っていれば '1abcd'に書き込み、' 2abc'があれば '2abcd'に書き込み、' 3abc'があれば '3abcd' ...私は、変数1の同じ名前(部分的に同じ)から変数2の名前を取得する方法を意味します。 – Danny

+1

別の変数である変数名を使用して変数に書き込むことはできません。 "変数名"としてキーを使用して辞書を使用してください – Paulw11

答えて

4

Swiftはコンパイルされた静的な言語であり、オプティマイザはこれらの一時変数を必要としない場合は完全に削除することができます。ローカル変数の名前は実行時には利用できません。このアプローチはうまくいきません。あなたが辞書を使って "first"と "second"をストリングキー(Paulw11があなたを指し示している場所)として保持していればうまくいくかもしれませんが、これはSwiftの間違ったアプローチです。

dictから始めましょう。これは辞書の適切な使用ではありません。これは、文字列と文字列との任意のマッピングではありません。これは、固有のフィールド識別子の値へのマッピングです。それが構造体の定義です。

「タイプ」は実際には「任意の整数」である可能性がありますが、実際には「値の制約付きリストからの値」であることが強く疑われます。それはenumです。

私たちは一緒にそれらを置く場合、辞書は本当に要素である:

enum ElementType { 
    case one 
    case two 
    case three 
    case four 
} 

struct Element { 
    let type: ElementType 
    let word: String 
} 

そして、あなたの名前のセレクタはElementTypesの任意のリストです:

let firstNameTypes = [ElementType.one, .two] 
let secondNameTypes = [ElementType.three, .four] 

その後、むしろただ一つのdictよりも、私たちは想像することができます要素のリスト(あなたが実際にこのループの外にいると仮定します)。

let elements = [ 
    Element(type: .one, word: "abc"), 
    Element(type: .two, word: "bcd"), 
    Element(type: .three, word: "efg"), 
    Element(type: .four, word: "fgh"), 
] 

私たちのループは些細なことであり、明らかにそれが何を意味していますか?

let firstNames = elements.filter { firstNameTypes.contains($0.type) } 
let secondNames = elements.filter { secondNameTypes.contains($0.type) } 

そして、我々の最後の文字列を取得することも簡単です:

let firstString = firstNames.map { $0.word }.joined(separator: ",") 
let secondString = secondNames.map { $0.word }.joined(separator: ",") 

このコードは非常に明確であるが、それは二回、各要素について一度「NameTypes」リスト上の要素を反復ありません。大多数の場合、それは問題ありません。それはコンピュータのことですが、何千もの要素がある場合(特に名前のフィルタリングリストが長い場合は)、コストが高くなる可能性があり、結果文字列の辞書を返す関数を書くことができます(手でfilterを書き換えます)。それがあなたの問題なら、それを書くことができます(根本的な問題をより明確に説明するならば)。しかし、ほとんどの場合、控えめなサイズのリストでは、これが最善の方法です。

+0

よく書かれています。私は書くつもりだった。しかし、 'let firstNameTypes:[ElementType] = [.one、.two]'のような名前セレクタをキャストすることはできます。 –

+1

ええ;私は本当に最高のスタイルがそれにどういうものか決まっていません。最初の要素を明示したり、型を指定したりしてください。私はどちらが良いかについての強い意見はありません。 (あなたのアプローチを「キャスティング」と呼ぶわけにはいきませんが、それは不正確で、混乱の原因となる可能性があります)あなたはそれを並べて見ると、 –

+0

@RobNapierあなたの答えに感謝します。投票を設定するのではなく、誰かが詳細に答えたときは本当に素晴らしいです。ところで、あなたの答えにバグがあります。 'let firstString = firstNames.map {$ 0.word} .joined(separator:"、 ")' ---> 'String型の値に 'joined joined'というメンバーはありません – Danny

-2

私の推測では、 'val'は一時変数で、 'dict'辞書に影響するように割り当てることはできません。あなたはあなたのコードで達成しようとしているかを説明するかどう代わり

dict[key] = ... 

また使用

val = .. 

試してみるの

は、それは素晴らしいことです。

+0

これは返されます_代理人は添え字を使って代入することはできません。また、 'dict [key]'はdictに書き込むでしょう。 – Danny

関連する問題