2015-01-21 55 views
0

我試圖創建一個函數,它將一個列表作爲參數,並返回第一個字母的類型作爲列表的名稱,以及這些字母的數量,用於例如,如果我的名單看起來是這樣的:計算列表中的名字的第一個字母

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 
} 

,但由於某種原因,在我的其他語句也不會加字母,只返回:

["r": 1, "o": 1, "p": 1, "s": 1, "t": 1] 

,我想不通爲什麼。

如果任何人都能看到爲什麼,或者有更好的解決方案來解決我的問題,我會非常感激。

+0

我不是一個很好的快速閱讀器,但是不應該在if分支中將該字母添加到列表中嗎? list似乎對我無條件保持爲空 – danh 2015-01-21 00:20:29

+0

yeah正如danh所說,list總是空的,並且從不附加到 – chris 2015-01-21 00:32:00

+0

而不是'var list = [String](countDict.keys)'use dict'var firstCount = [String:Int]( )'來計數事件。 – 2015-01-21 00:34:03

回答

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 
} 
0

,你也可以利用地圖,減少產生的輸出

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) 
0

您可以使用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 
    }) 
} 
相關問題