美文网首页程序员
Swift 4 Dictionary and Set 的变化

Swift 4 Dictionary and Set 的变化

作者: Lucky闪闪星 | 来源:发表于2018-01-12 21:50 被阅读159次

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 的变化

    本文链接:https://www.haomeiwen.com/subject/wjrqoxtx.html