2016-03-22 157 views
0

此代碼用於按字母組合一個字符串數組。將兩個循環合併爲一個

//plain array 
var list = ["apple", "apricot", "banana", "blackberry"] 

//dictionary of arrays 
var dict = Dictionary<String, Array<String>>() 

//create necessary keys from first characters 
for word in list { 
    dict[ String(word.characters.prefix(1)) ] = [ ] 
} 

//add words to the key of their first character 
for word in list { 
    dict[ String(word.characters.prefix(1)) ]?.append(word) 
} 

//output dictionary 
print(dict) 

此示例將輸出詞典這樣的:

[ "b": ["ba", "bb"], 
    "a": ["aa", "ab"] ] 

的代碼有兩個類似for環路。它們可以組合成一個單一的環路而不影響輸出嗎?

回答

3

聽起來像一個groupBy功能的完美的工作:

extension Array { 
    func groupBy<T: Hashable>(f: Element -> T) -> [T: [Element]] { 
     var results = [T: [Element]]() 
     for element in self { 
      let key = f(element) 
      if results[key] != nil { 
       results[key]!.append(element) 
      } else { 
       results[key] = [element] 
      } 
     } 
     return results 
    } 
} 

var list = ["apple", "apricot", "banana", "blackberry"] 
let dict = list.groupBy { 
    String($0.characters.prefix(1)) 
} 

讓我們通過它一步一步:

  • groupBy接受一個函數,給出了一個關鍵的每個元素的數組。它返回一個字典,其中包含鍵和具有相同鍵的元素列表。
  • f是那個鍵給功能。對於數組中的每個元素,檢查結果字典是否已經有該鍵。如果是,它將被追加到該鍵的元素列表中。如果否,則爲該密鑰創建一個新數組。
+0

這很有道理。我沒有想到'groupBy'。所以這個函數只需要檢查在添加元素之前是否已經創建了該鍵。 –

+0

是否可以保存密鑰的順序? –

+1

詞典沒有順序。獲取密鑰列表,對它們進行排序,然後按照該順序遍歷字典 –

1
//plain array 
    let list = ["apple", "apricot", "banana", "blackberry"] 

    //dictionary of arrays 
    var dict = Dictionary<String, Array<String>>() 

    //create necessary keys from first characters 
    for word in list { 

     if let _ = dict[ String(word.characters.prefix(1))] { 
      dict[ String(word.characters.prefix(1))]?.append(word) 
     } 
     else{ 
      dict[ String(word.characters.prefix(1)) ] = [word] 
     } 
    } 

    //output dictionary 
    print(dict)