Swift中的NSCountedSet枚举

时间:2016-12-01 15:36:47

标签: swift3 enumeration nscountedset

我正在寻找一种方法,以更NSCountedSet的方式使用Swift(无论这意味着什么)。

考虑以下基本上我直接从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 个答案:

答案 0 :(得分:1)

您可以在flatMap上链接reduce后跟symbolSet操作,

  • flatMap操作会尝试将symbolSet成员转换为String
  • 以下reduce操作计算count中符号symbolSet的加权和(对于成功转换为String个实例的符号)

示例设置:

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

使用已链接的flatMapreduce操作计算加权累计总和(预期结果: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