2016-12-01 10 views
0

NSCountedSetをより多くのSwiftのように使用する方法を探しています(その意味は問わない)。SwiftのNSCountedSet列挙

基本的にObjective Cから直接翻訳した次のスニペットを考えてみましょう。セット内の各シンボル(String)を繰り返し処理し、対応するカウントを取得して、そのシンボルの値を辞書で検索します。その値に数を掛けて合計に加えます。

var total = 0 

for symbol in symbolSet { 
    let count = symbolSet.count(for: symbol) 
    let item = symbolDictionary[symbol as! String] 
    let value = item?.value 

    total+= (count * value!) 
} 

それは動作しますが、私はXcodeが私のために提案されていることアンラップについて少し心配です。だから私はこれをもっともっとSwiftのようなやり方にしようとしているので、すべてのアンラッピングなしでより安全です。

私はこのような何かを開始しました:

symbolSet.enumerated().map { item, count in 
    print(item) 
    print(count) 
} 

しかし、ここでカウント実際のカウントが、列挙インデックスではありません。

これを進めるにはどうすればよいですか?

答えて

1

あなたは可能性が連鎖あなたsymbolSetreduce操作が続くflatMap

  • flatMap操作がString
  • symbolSetメンバーの未遂変換を適用し、次のreduce操作がcountの加重和を計算symbolSetStringインスタンスに正常に変換されたシンボルの場合)

例のセットアップ:チェーンflatMapreduce操作で

struct Item { 
    let value: Int 
    init(_ value: Int) { self.value = value } 
} 

let symbolDictionary = [ 
    "+" : Item(1), 
    "-" : Item(2), 
    "/" : Item(4), 
    "*" : Item(8) 
] 

var symbolSet = NSCountedSet() 
symbolSet.add("*") // accumulated: 8 
symbolSet.add("/") // accumulated: 8 + 4 = 12 
symbolSet.add("+") // accumulated: 12 + 1 = 13 
symbolSet.add("-") // accumulated: 13 + 2 = 15 
symbolSet.add("+") // accumulated: 15 + 1 = 16 

計算加重累積合計(期待される結果:16):

let total = symbolSet 
    .flatMap { $0 as? String } /* <- attempted conversion of each symbol to 'String'   */ 
    .reduce(0) { $0 + symbolSet.count(for: $1) * (symbolDictionary[$1]?.value ?? 0) } 
       /* | ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
        |    |    If a key exists for the given symbol as a 
        |    |    String, extract the 'value' property of the 
        |    |    'Item' value for this key, otherwise '0'. 
        |    | 
        | Multiply '...value' or '0' with the 'count' for the given symbol. 
        \ 
        Add the product to the accumulated sum of the reduce operation.   */ 

print(total) // 16, ok 
+0

これは非常に有望に見える、私はこれをテストすることができるようになりますこの日の後半。 – Koen

+0

@Koenお手伝いします。次回質問を投稿するときには(例えば、私の 'Item'定義と私の' symbolDictionary'と 'symbolSet'インスタンス化のような)[最小、完全で検証可能な例](http://stackoverflow.com/help/mcve)これは、将来の回答者があなたを手助けすることを容易にするので、あなたはsatiesfactoryの回答を得ることになる変化を増やすようになります:) – dfri

+0

あなたの例は私のケースにかなり近かった。 'value'だけは実際には2つの' Double'プロパティの構造体ですので、いくつかの頭出しの後に '.reduce'行の始めと終わりに' 0'を置き換えて '' double'sがセットされた "zero struct" 「0」に設定する。そしてすべての作品! – Koen