Swift中的字数统计

时间:2014-06-08 23:50:09

标签: algorithm swift

在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]

4 个答案:

答案 0 :(得分:7)

你的方法非常扎实,但这会带来一些改进。我使用Swifts&#34来存储值计数;如果让&#34;用于检查可选值的关键字。然后我可以在更新字典时使用count。我使用updateValue的简写表示法(dict [key] = val)。我还在所有空格上拆分原始字符串,而不是仅仅一个空格。

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
}

答案 1 :(得分:3)

我不认为这更优雅,因为可读性非常糟糕,它需要和扩展字典,但它写起来非常有趣并向您展示了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")

我确实认为合并扩展在其他情况下会很有用

答案 2 :(得分:1)

在集合库中找不到Counter类型的任何痕迹。 您可以使用可选链接稍微改进代码。

func wordCount(s: String) -> Dictionary<String, Int> {
    var words = s.componentsSeparatedByString(" ")
    var wordDictionary = Dictionary<String, Int>()
    for word in words {
        if wordDictionary[word]? {
            wordDictionary[word] = wordDictionary[word]! + 1
        } else {
            wordDictionary[word] = 1
        }
    }
    return wordDictionary
}

wordCount("foo foo foo bar")

答案 3 :(得分:0)

可能不优雅但实施起来很有趣

let inString = "foo foo foo bar"

func wordCount(ss: String) -> Dictionary<String, Int> {
    var dict = Dictionary<String, Int>()
    var tempString = "";var s = ss + " "
    for each in s{
        if each == " "{ if dict[tempString] {
                var tempNumber = Int(dict[tempString]!)
                dict[tempString] = Int(tempNumber+1)
                tempString = ""
            } else {dict[tempString] = 1;tempString = ""}
        } else {
            tempString += each}}
    return dict
}

println(wordCount(inString))