我正在尝试创建一个以列表作为参数的函数,并返回名字作为列表的首字母类型,以及这些字母的数量,例如,如果我的列表如下所示:
let thisList:[String] = ["Roman", "Serial", "Thomas", "Peter", "Pan", "Other", "Peter", "Remy"]
我希望我的函数的输出看起来像这样:
["r": 2, "o": 1, "p": 3, "s": 1, "t": 1]
我的功能目前看起来像这样:
func listCounter(usernames: [String])->Dictionary<String,Int>{
var countDict : [ String : Int ] = [:]
var list = [String](countDict.keys)
for user in usernames{
let index = advance(user.startIndex, 0)
//Retrieving the first letter of the name and converting it to a string
var letter = "\(user[index])" as String
letter = letter.lowercaseString
//Checking if the list already has the letter in it
if (find(list, letter) == nil){
countDict[letter] = 1
println("Letter not found, not appended")
//If the letter is in the list, add its current value to 1
}else{
let number = Int(countDict[letter]!)
countDict[letter] = number + 1
}
}
return countDict
}
但由于某种原因,它不会在我的else语句中添加字母,只返回:
["r": 1, "o": 1, "p": 1, "s": 1, "t": 1]
我无法弄明白为什么。
如果有人能够理解为什么,或者对我的问题有更好的解决方案,我会非常感激。
答案 0 :(得分:0)
NSCountedSet
可以帮到你。实际上你可以只返回一个NSCountedSet
并在最后跳过字典的创建。
func listCounter(usernames: [String])->Dictionary <String,Int> {
let countedSet=NSCountedSet()
for user in usernames{
let index = user.substringToIndex(advance(user.startIndex,1))
countedSet.addObject(index.lowercaseString)
}
var dict=Dictionary<String,Int>()
let letters = countedSet.objectEnumerator().allObjects as [String]
for letter in letters {
dict[letter]=countedSet.countForObject(letter)
}
return dict
}
答案 1 :(得分:0)
您还可以使用map-reduce来生成输出
let thisList = ["Roman", "Serial", "Thomas", "Peter", "Pan", "Other", "Peter", "Remy"]
func firstLetterCountOfList(list: [String]) -> [String:Int] {
let mappingFunction = { (x: String) -> String in
let index = advance(x.startIndex, 0)
return String(x[index]).lowercaseString
}
let reducingFunction = { (x:[String:Int], y:String) -> [String:Int] in
var output = x
if let count = output[y] {
output[y] = count + 1
}
else {
output[y] = 1
}
return output
}
return list.map(mappingFunction).reduce([:], reducingFunction)
}
firstLetterCountOfList(thisList)
答案 2 :(得分:0)
您可以使用nil coalescing运算符进一步减少已使用reduce
的已解决方案中的代码。 http://www.codingexplorer.com/nil-coalescing-swift/
successor
函数获取元素的后继函数。如果元素为1则返回2.
let thisList = ["Roman", "Serial", "Thomas", "Peter", "Pan", "Other", "Peter", "Remy"]
func firstLetterCountOfList(list: [String]) -> [String:Int] {
return list.reduce([:], { (var letterCount, name) -> [String:Int] in
//Create the range to get first character.
let range = advance(name.startIndex, 0)
//Extract the first character here.
let char = String(name[range]).lowercaseString
/* This sets the character count to 1 if the char does
not exist in the dictionary. ?? is nil coalescing operator.*/
letterCount[char] = letterCount[char]?.successor() ?? 1
return letterCount
})
}