Я думаю, что использование Tuple
не очень хорошая идея.Вместо этого вы можете изменить его на какой-то тип.Например:
struct Frequency: Equatable {
let char: Character
let count: Int
}
Struct
хорошо, это тип значения (как Tuple
), и может автоматически синтезировать соответствие Equatable
протоколу .
Следующим шагом является класс Huffman
.Для такой крошечной проблемы у вас есть тонна кода.Давайте попробуем также изменить его:
final class Huffman {
private(set) var frequency: [Frequency]
init(_ input: String) {
frequency = input.counts
.map { Frequency(char: $0.key, count: $0.value) }
.sorted(by: { $0.count > $1.count })
}
}
extension String {
var counts: [Character: Int] {
return reduce(into: [:]) { d, c in
d[c] = d[c, default: 0] + 1
}
}
}
Обратите внимание, этот код вычисляет частоту в свойстве String
расширения counts
(возможно, не в лучшем названии), затем map
приводит к [Frequency]
инаконец, сортировка это не большая проблема.Гораздо меньше кода и больше точности.
И здесь мы проведем наш единственный тест:
func testFrequencyCountOnInput() {
let huff = Huffman("ANNNA")
let expected: [Frequency] = [
Frequency(char: "N", count: 3),
Frequency(char: "A", count: 2)
]
XCTAssertEqual(huff.frequency, expected)
}
Все отлично работает, даже функция sort
.