Swift4中的字典和集合在这些方面变得更好
写在前面
在最新版本的Swift中,dictionaries和sets新增了很多行为方法和初始化方法,让一些常见的任务变得异常简单。诸如组合、过滤和transform值操作可以用一步完成,让使用者可以写出更高效和简洁的代码。
本篇博客将使用杂货铺中的商品作为例子演示这些新功能。GroceryItem结构体,由名字和部门组成,作为本例的数据类型。
|
|
后面的例子将围绕着groceries数组展示。
用Key值对原数组进行分组
字典拥有了一个新的初始化函数,可以将一系列值按照Key值进行分组。下面展示使用该初始化方法根据GroceryItem的department进行分组的一个小例子。
在老版本的Swift中,用户可以使用如下的代码完成上述任务。
|
|
这一过程需要使用type annotations、手动循环并且需要检查departement是否已经存在了。
在Swift4中,用户可以使用Dictionary(grouping:by)方法,仅需一行代码就可以达到上述效果。所要做的是传入一个闭包,该闭包返回数组每一项项对应的Key值即可。
|
|
最终的字典groceriesByDepartment对每个department都有唯一入口,而且该入口对应着GroceryItem相应的name。例如,使用.bakery作为入口,将返回[🥐, 🍞]数组。
获得字典值的数量
使用新的mapValues(_:)方法,用户可以方便的获得每个入口对应数组的长度。以上面例子中获取的groceriesByDepartment字典为例:
|
|
因为字典有相同的key,只是值不同,所以可以不需要重新计算哈希值,从而使得调用mapValues(_:)方法比从头建立字典快很多。
从键值对建立字典
Swift4提供了两种方法给用户从键值对序列生成字典,一种方法允许key有重复,另一种不允许。
使用zip(::)函数可以将一些了键值组合起来。例如下面的代码就创立了一系列(String,GroceryItem)元组。
|
|
zippedNames的每一项都是一个元组(tuple),第一项是(“Apples”, 🍎).因为name值是唯一的,下面的方法就可以创建一个字典,也是我们上面提到的不允许key值重复的方法。
|
|
当然,要使用该方法的前提是你可以确保key值是不重复的。否则会引起runtime error。
如果key值可能会重复,使用另一个方法:Dictionary(_:uniquingKeysWith:)。这个方法需要传入一个闭包来处理当key重复时的操作。闭包的第一个参数是key(键)对应的old value(值),而第二个对应的是新值。用户可以在闭包里写相应的逻辑,比如新值替代老值,或者将新老值合并。
|
|
看上面的例子,dog对应了两个值。当方法处理到(“dog”, “🐶”)时,闭包的参数是 (“🐕”, “🐶”),而闭包的逻辑是返回第二个值,因此新值就代替了老值,最终的字典中,dog对应的值就是🐶。
筛选出特定的项
字典现在有了一个filter(_:)方法,返回值是满足条件的新字典(早期版本的swift返回的是一个数组)。方法传入的参数依然是一个闭包,如果某一项需要在返回值中出现,闭包返回true,否则返回false。
|
|
上例中,isOutOfStock决定某一项该不该出现在返回值字典中。
使用默认值
字典现在提供了类似数组下标来获取和更新值,下面的代码定义了一个简单的购物篮,key是商品,value是商品的数量。
|
|
因为某些key在字典中没有对应的值,因此你用key去获取值的时候,返回结果是optional的。
|
|
可以使用??操作符将optinal值拆包为真实的数值,现在swift4提供了另一种解决方案(设置默认值),如果key对应的值存在,那么返回该值,否则返回默认值。如果key没有对应值,那么返回默认值。
|
|
甚至用下面的代码简化增加新item到购物车的过程。
|
|
当循环处理到🍌时,检索到当前值,然后自增,放回到原字典中。当检索到🍞时,发现🍞现在并没有对应值,从而返回默认值0,自增为1,存储到字典中,下次检索的时候就变成了1.
合并两个字典到一个字典中
将两个字典合并也变得异常简单。swift4提供了merge(_:uniquingKeysWith:)方法来处理合并操作。和上面一样,需要传入一个闭包完成合并的逻辑,当两个字典拥有相同的key值时,由该闭包处理如何操作。
|
|
上面的代码将相同key对应的值相加作为新字典中的值。
如果不想原地合并,可以使用merging(_:uniquingKeysWith:)方法生成一个新字典。
And That’s Not All…
上面介绍的新特性并不是全部,限于篇幅,并没有完全介绍全。
和字典一样,集合也拥有了新的filter(_:) 方法,返回的也是集合,而不是早起版本中的数组。字典和集合现在提供了暴漏现在capacity的方法:reserveCapacity(_:),有了该方法,用户可以看到并控制他们的内部存储。
Reference
本文译自:https://swift.org/blog/dictionary-and-set-improvements/
原文作者: Chih-Hao
原文链接: http://zhihaozhang.github.io/2017/10/13/DicAndSetInSwift4/
发表日期: October 13th 2017, 2:02:20 pm
版权声明: 本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可
-
Next Post拓扑图的实现
-
Previous Post元素加上边框和背景色 >为SVG中大小可变的
元素加上边框和背景色