What is a more elegant way of writing a simple word count function in Swift?
//Returns a dictionary of words and frequency they occur in the string
func wordCount(s: String) -> Dictionary<String, Int> {
var words = s.componentsSeparatedByString(" ")
var wordDictionary = Dictionary<String, Int>()
for word in words {
if wordDictionary[word] == nil {
wordDictionary[word] = 1
} else {
wordDictionary.updateValue(wordDictionary[word]! + 1, forKey: word)
}
}
return wordDictionary
}
wordCount("foo foo foo bar")
// Returns => ["foo": 3, "bar": 1]
Your method was pretty solid, but this makes a couple improvements. I store the value count using Swifts "if let" keyword to check for an optional value. Then I can use count when updating the dictionary. I used the shorthand notation for updateValue (dict[key] = val). I also split the original string on all whitespace instead of just a single space.
func wordCount(s: String) -> Dictionary<String, Int> {
var words = s.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
var wordDictionary = Dictionary<String, Int>()
for word in words {
if let count = wordDictionary[word] {
wordDictionary[word] = count + 1
} else {
wordDictionary[word] = 1
}
}
return wordDictionary
}
I don't think this is more elegant because the readability is terrible and it requires and extension on Dictionary but it was really fun to write and shows you the potential power of swift:
extension Dictionary {
func merge(with other: [KeyType:ValueType], by merge: (ValueType, ValueType) -> ValueType) -> [KeyType:ValueType] {
var returnDict = self
for (key, value) in other {
var newValue = returnDict[key] ? merge(returnDict[key]!, value) : value
returnDict.updateValue(newValue, forKey: key)
}
return returnDict
}
}
func wordCount(s: String) -> [String:Int] {
return s.componentsSeparatedByString(" ").map {
[$0: 1]
}.reduce([:]) {
$0.merge(with: $1, +)
}
}
wordCount("foo foo foo bar")
I do think that merge extension would be useful in other circumstances though
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With