搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > SwiftCafe > Swift 4.0 中对 Dictionary 的一系列改进

Swift 4.0 中对 Dictionary 的一系列改进

SwiftCafe 2018-03-01

Swift 4 发布已经有一段时间了, 不知道大家有没有切换到 4.0 版本。 这次 4.0 更新给我最大的感受就是没有了前几次升级的跳跃式变化。 不用为了更新语言版本,完全推翻已有的项目,这也是 Swift 慢慢趋向于稳定的标志。

咱们这次说说 Swift 4.0 对 Dictionary 这个经常会用到的类的改进。

自动根据 key 分组

Dictionary 新增了一个构造方法,可以将给定的一个数组,根据指定的条件进行分组。 来看一个例子:

struct Person {

   var name: String
   var gender: Gender
   var age: Int

    enum Gender {
        case male
        case female
   }

}

这里有一个 Person 结构, 然后我们初始化一个数组:

let p1 = Person( name: "aa", gender: .female, age: 22)
let p2 = Person( name: "bb", gender: .male, age: 24)
let p3 = Person( name: "cc", gender: .male, age: 21)

let persons = [p1, p2, p3]

现在用新的 Dictionary 构造方法,可以立即将这组 Person 实例根据他们的 gender 属性进行分组:

let groupedDict = Dictionary(grouping: persons) { p in

   return p .gender

}

这个构造方法,第一个参数 grouping 接收的是 persons 数组, 第二个参数是一个闭包,用于返回根据进行分组的依据,我们这里返回的是 p.gender。结果一目了然:

[
   .male: [
       Person(name: "bb", gender: .male, age: 24),
       Person(name: "cc", gender: .male, age: 21)
   ],
   .female: [
       Person(name: "aa", gender: .female, age: 22)
   ]
]

以往要实现这样的功能,就需要手动遍历整个数组,取出 key, 然后生成字典, 现在方便很多。

value 无缝转换

另外一个比较有用的特性是,Dictionary 提供的 mapValues 方法。 还以我们刚才生成的 groupedDict 为例,可以进行这样的操作:

let count = groupedDict .mapValues { persons in
   persons .count
}

先看一下输出,大家可能就猜到这个方法的用途是什么了:

[
    .male: 2,
    .female: 1
]

上面的输出可以看到, mapValues 会遍历每一个 key 对应的 values, 然后传递给闭包进行自定义转换。 我们例子中的闭包返回的就是每个 key 对应的 Person 集合的数量,最生成了一个新的 Dictionary,里面的 key 和之前一样,只是对应的值变成了我们闭包中自定义的了。

mapValues 方法同样是一个帮助我们解决繁杂操作的工具方法。 

从键值对元组中直接构建

假如我们有这样一个数组:

let personsTuples = [( "group 1", [ p1, p2]),  ( "group 2", [ p3])]

然后可以调用 uniqueKeysWithValues 构造方法直接初始化字典:

let dict = Dictionary( uniqueKeysWithValues: personsTuples)

personsTuples 数组中,每一个元素都是一个元组(Tuple), 这个构造方法把元组中的第一项当做 key, 第二项当做 value, 生成一个新的 Dictionary,如下所示:

[
    "group 1": [
       Person(name: "aa", gender: .female, age: 22),
       Person(name: "bb", gender: .male, age: 24)
   ],
    "group 2": [
       Person(name: "cc", gender: .male, age: 21)
   ]
]

使用 uniqueKeysWithValues 构造方法时候需要注意,就是传入的数组中,不能有重复的 key, 否则会报运行时错误,比如这个数组就会报错:

let personsTuples = [( "group 1", [ p1, p2]),  ( "group 2", [ p3]), ( "group 2", [ p4])]

上面数组中 group 2 出现了两次。 如果用它来初始化的话,就会出错。 所以 Swift 4.0 还提供了另外一个初始化方法, 对于上面这个数组,可以调用:

let dict = Dictionary(personsTuples) { old, new in
    return new
}

第二个闭包参数,会在遇到重复的 key 时候调用。 它提供两个参数,一个是同样这个 key 的上一个值 old, 还有当前的值 new。 我们这里直接返回 new,意思就是 每次遇到重复的 key, 就用新的值代替老的值。 这样初始化后,生成的 Dictionary 结构如下:

[
    "group 1": [
           p1,
           p2
   ],
    "group 2": [
           p4
   ]
]

group 2 中的值, 是第二次 key 所对应的 p4。

提供默认值

如果我们访问了一个字典中不存在的 key, 会返回 nil:

dict[ "group 3"]

因为上面字典中,不存在 group 3 这个 key, 所以它返回了 nil。 Swift 4 中新增了指定默认值的能力:

dict[ "group 3", default: []]

这样调用,如果 group 3 这个 key 不存在的话, 就会返回我们指定的默认值空数组, 而不是 nil 了。 这个特性在我们处理 JSON 数据解析这类的问题上很实用。

过滤器

过滤器对于集合类来说是比较常用的功能。 Swift 4 中对 Dictionary 类型也提供了过滤器的支持:

let filteredDict = dict.filter { key, val in

    return val.count >= 2

}

filter 方法接收一个闭包,它会遍历 Dictionary 中所有的元素,并且作为闭包的参数传入。 我们需要通过闭包的返回值确定这个元素是否被保留。 上面的例子中,比如我们 dict 中的元素是 :

[
    "group 1": [
           p1,
           p2
   ],
    "group 2": [
           p4
   ]
]

调用 filter 后,我们只保留数量大于 2 的集合:

[
    "group 1": [
           p1,
           p2
   ]
]

总结

以上就是 Swift 4.0 对于 Dictionary 的主要改进。 这些新增的工具方法对于提高我们开发效率和代码质量都有帮助,希望这里的介绍对你有帮助。 关于 Dictionary 更完整的信息,大家还可以参考苹果官方的文档,还有 Swift Blog 中的介绍。

Dictionary 官方文档 https://developer.apple.com/documentation/swift/dictionary 

Swift Blog: https://swift.org/blog/dictionary-and-set-improvements/



版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《Swift 4.0 中对 Dictionary 的一系列改进》的版权归原作者「SwiftCafe」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注SwiftCafe微信公众号

SwiftCafe微信公众号:swift-cafe

SwiftCafe

手机扫描上方二维码即可关注SwiftCafe微信公众号

SwiftCafe最新文章

精品公众号随机推荐