2016-03-22 159 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)