2016-12-01 6 views
0

Я ищу способ использовать NSCountedSet в более чем Swift-like way (независимо от того, что это означает).Перечисление NSCountedSet в Swift

Рассмотрите следующий фрагмент, который я в основном перевел непосредственно с Objective C. Я перебираю каждый символ (a 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

Вы можете ЦЕПЬ 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 

Вычисление взвешенных накопленную сумму с прикованными flatMap и reduce операций (ожидаемый результат: 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 рады помочь. Рассмотрите возможность включения [минимального, полного и проверяемого примера] (http://stackoverflow.com/help/mcve) в следующий раз, когда вы отправляете вопрос (например, мое определение 'Item' и мои экземпляры' symbolDictionary' и 'symbolSet', которые я ' вы включили выше), так как это облегчит для потенциальных ответчиков, чтобы помочь вам, что, в свою очередь, увеличит изменение, которое вы получите ответ satiesfactory :) – dfri

+0

Ваш пример был очень близок к моему делу. Только 'значение' на самом деле является структурой двух свойств« Double », поэтому после некоторого сокращения я заменил« 0 »в начале и конце строки' .reduce' с «нулевой структурой», причем оба набора '' Double '' до '0'. И все работает! – Koen

Смежные вопросы