神刀安全网

Swift 4 Dictionary and Set 的变化


Dictionary and Set

Collection类型,SetDictionary并不那么最直观的。幸运的是,Swift 团队对两者做了很好的改进 [SE-0165]

Sequence Based Initialization

首先列表可以是从一系列键值对(元组)创建一个字典:

 let nearestStarNames = ["Proxima Centauri", "Alpha Centauri A", "Alpha Centauri B", "Barnard's Star", "Wolf 359"]  let nearestStarDistances = [4.24, 4.37, 4.37, 5.96, 7.78]   // Dictionary from sequence of keys-values  let starDistanceDict = Dictionary(uniqueKeysWithValues: zip(nearestStarNames, nearestStarDistances))  // ["Wolf 359": 7.78, "Alpha Centauri B": 4.37, "Proxima Centauri": 4.24, "Alpha Centauri A": 4.37, "Barnard's Star": 5.96]  
Duplicate Key Resolution

在初始化Dictionary时, 你现在可以使用你喜欢的方式来处理重复的键,同时避免覆盖键值对,且不会出现任何问题:

   // Random vote of people's favorite stars   let favoriteStarVotes = ["Alpha Centauri A", "Wolf 359", "Alpha Centauri A", "Barnard's Star"]    // Merging keys with closure for conflicts  let mergedKeysAndValues = Dictionary(zip(favoriteStarVotes, repeatElement(1, count: favoriteStarVotes.count)), uniquingKeysWith: +) // ["Barnard's Star": 1, "Alpha Centauri A": 2, "Wolf 359": 1]  

上面的代码使用了 zip+ 来快捷地处理重复的 key 和冲突的值。

注意:如果你不熟悉 zip,你可以在Apple的Swift文档中快速了解它 [Swift Documentation]  
Filtering

Dictionary 和 Set现在都可以将结果 通过filter函数 过滤到原始类型的新对象中:

    // Filtering results into dictionary rather than array of tuples  let closeStars = starDistanceDict.filter { $0.value < 5.0 }   closeStars // Dictionary: ["Proxima Centauri": 4.24, "Alpha Centauri A": 4.37, "Alpha Centauri B": 4.37]  
Dictionary Mapping

Dictionary为直接映射其值提供了一种非常有用的方法::

  // Mapping values directly resulting in a dictionary   let mappedCloseStars = closeStars.mapValues { "/($0)" }    mappedCloseStars // ["Proxima Centauri": "4.24", "Alpha Centauri A": "4.37", "Alpha Centauri B": "4.37"]  
Dictionary Default Values

在Dictionary上访问某个值时,常见的做法是使用nil-coalescing operator给出默认值(译者注: 不了解nil-coalescing operator 的伙伴 可参见Nil-Coalescing OperatorDictionary Default Values可以更简洁:

   // Subscript with a default value   let siriusDistance = mappedCloseStars["Wolf 359", default: "unknown"] // "unknown"     // Subscript with a default value used for mutating    var starWordsCount: [String: Int] = [:]    for starName in nearestStarNames {         let numWords = starName.split(separator: " ").count         starWordsCount[starName, default: 0] += numWords // Amazing      }   starWordsCount // ["Wolf 359": 2, "Alpha Centauri B": 3, "Proxima Centauri": 2, "Alpha Centauri A": 3, "Barnard's Star": 2]  

swift4之前, 处理这种情况需要包装在臃肿的if - let语句中。现在简短的代码即可.

Dictionary Grouping

另一个令人惊讶称赞的是,我们可以从Sequence“中初始化Dictionary,并将其分组为bucket::

 // Grouping sequences by computed key  let starsByFirstLetter = Dictionary(grouping: nearestStarNames) { $0.first! }   // ["B": ["Barnard's Star"], "A": ["Alpha Centauri A", "Alpha Centauri B"], "W": ["Wolf 359"], "P": ["Proxima Centauri"]]  

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Swift 4 Dictionary and Set 的变化

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址