有没有一种方法可以创建默认字典来计算字符/字符串/其他内容? Python有方便的Counter()类,但是我找不到能实例化任何东西的Swift,类似于Array(repeating:0,count:x)。我知道我可以自己做。我在问Foundation是否已经有类似的东西了……因为我找不到它。谢谢!
更新 以下是最接近的两个答案: 通过@matt
let s = "abracadabra"
let letters = s.map {String($0)}
var countedLetters = [String:Int]()
letters.forEach {countedLetters[$0, default:0] += 1}
countedLetters // ["b": 2, "a": 5, "r": 2, "d": 1, "c": 1]
和其他人:
let letters: [Character] = ["a", "b", "c"]
let countedLetters: [Character: Int] = Dictionary(uniqueKeysWithValues: zip(letters, repeatElement(1, count: letters.count)))
print(countedLetters)
我只是希望在所有这些之上建立一个抽象,类似于Python的Counter()。
它显然不存在。谢天谢地扩展:)
旧示例问题
例如:
let letters = ["a", "b", "c"]
let countedLetters: [Character: Int] = Dictionary(default: 1, forKeys: letters)
print(countedLetters)
// "a": 1
// "b": 1
// "c": 1
答案 0 :(得分:3)
赞:
var countedLetters = [String:Int]()
letters.forEach {countedLetters[$0, default:0] += 1}
示例:
let s = "abracadabra"
let letters = s.map {String($0)}
var countedLetters = [String:Int]()
letters.forEach {countedLetters[$0, default:0] += 1}
countedLetters // ["b": 2, "a": 5, "r": 2, "d": 1, "c": 1]
答案 1 :(得分:3)
您可以使用Dictionary init(uniqueKeysWithValues:)
。这与文档中显示的示例非常相似。
let letters: [Character] = ["a", "b", "c"]
let countedLetters: [Character: Int] = Dictionary(uniqueKeysWithValues: zip(letters, Array(repeating: 1, count: letters.count)))
print(countedLetters)
输出:
[“ a”:1,“ b”:1,“ c”:1]
答案 2 :(得分:2)
如果您要计算字母,则不需要。您可以只使用Dictionary.subscript(_:default:)
extension Sequence where Element: Hashable {
func histogram() -> [Element: Int] {
return self.reduce(into: [:]) { dict, element in dict[element, default: 0] += 1 }
}
}
print("aaabbcc".histogram())
用法上仍存在细微差异。 Python的defaultdict
定义了defaultdict
创建期间丢失键的默认值,而此下标要求在访问时输入默认值。它更灵活,但可能不太方便。这取决于用例。
如果此使用模式不适合您的账单,则可以创建自己的DefaultDictionary
,包装字典,默认值并隐式使用Dictionary.subscript(_:default:)
。这是一个粗略的开始:
public struct DefaultDictionary<K: Hashable, V> {
public var dict = [K: V]()
public var defaultValueProducer: (K) -> V
public init(dict: [K: V], defaultValue: V) {
self.init(dict: dict, defaultValueProducer: { _ in defaultValue })
}
public init(dict: [K: V], defaultValueProducer: @escaping (K) -> V) {
self.dict = dict
self.defaultValueProducer = defaultValueProducer
}
private func produceDefaultValue(forKey key: K) -> V {
return self.defaultValueProducer(key)
}
public subscript(_ key: K) -> V {
get { return self.dict[key, default: produceDefaultValue(forKey: key)] }
set { self.dict[key, default: produceDefaultValue(forKey: key)] = newValue }
}
func reallyContains(key: K) -> Bool {
return self.dict[key] != nil
}
}
答案 3 :(得分:1)
正如罗伯提到的,您在可可中获得的最接近的是Objective-C类NSCountedSet:
touch /usr/local/etc/php/conf.d/extra_config.ini
echo extension_dir="/usr/lib/php/20180731/" >> /usr/local/etc/php/conf.d/extra_config.ini
echo extension=gd.so >> /usr/local/etc/php/conf.d/extra_config.ini
Running command php -m
答案 4 :(得分:1)
另外两个选项:
let results = Dictionary(grouping: s) { $0 }
.mapValues { $0.count }
这看起来很直观。效率不是很高,但这并不重要,除非您在 Moby Dick上执行此操作。
或者:
let results = s.reduce(into: [:]) {
$0[$1, default: 0] += 1
}
两者都很容易合而为一,但是我并不特别认为这会提高可读性。