Swift Dictionary:将值作为数组获取
Posted
技术标签:
【中文标题】Swift Dictionary:将值作为数组获取【英文标题】:Swift Dictionary: Get values as array 【发布时间】:2015-01-15 06:41:00 【问题描述】:我有一本字典,其中包含由枚举值 ColorScheme
散列的 UIColor
对象:
var colorsForColorScheme: [ColorScheme : UIColor] = ...
我希望能够提取此字典包含的所有颜色(值)的数组。我想我可以使用 values
属性,就像在遍历字典值 (for value in dictionary.values ...
) 时使用的那样,但这会返回一个错误:
let colors: [UIColor] = colorsForColorSchemes.values
~~~~~~~~~~~~~~~~~~~~~^~~~~~~
'LazyBidrectionalCollection<MapCollectionView<Dictionary<ColorScheme, UIColor>, UIColor>>' is not convertible to 'UIColor'
似乎values
方法不是返回值的Array
,而是返回更抽象的集合类型。有没有办法获得包含字典值的Array
而无需在for-in
循环中提取它们?
【问题讨论】:
Swift 5:colorsForColorSchemes.values
【参考方案1】:
从 Swift 2.0 开始,Dictionary
的 values
属性现在返回 LazyMapCollection
而不是 LazyBidirectionalCollection
。 Array
类型知道如何使用这个抽象集合类型来初始化自己:
let colors = Array(colorsForColorSchemes.values)
Swift 的类型推断已经知道这些值是UIColor
对象,所以不需要类型转换,这很好!
【讨论】:
您也可以将其转换为带有类型对象的数组。效果很好!谢谢 let colors = [CustomColorObject](colorsForColorSchemes.values) 看起来在 Swift 2.0 中,Dictionary.values 现在返回一个 LazyMapCollection 而不是 LazyBidirectionalCollection。不幸的是,.array 没有在 LazyMapCollection 上定义。但是,Array(dictionary.values) 方式仍然可以正常工作,因为数组类型知道如何从 LazyMapCollection 初始化自身。 请注意,值的顺序可能出乎意料。例如[0: "small", 1: "medium", 2: "large"]
可能不会 生成["small", "medium", "large"]
@SimonBengtsson 虽然这通常是个好建议,但 swift 文档确实表明 values
将按密钥对顺序排列,至少从 Swift 4 开始。“当迭代时,值出现在这个集合中与它们在字典的键值对中出现的顺序相同。” developer.apple.com/documentation/swift/dictionary/…
意外的部分是密钥对顺序与代码中定义的顺序不同,如您链接的文档中的示例所示。迭代和打印提到的字典 ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
Japan 的值时,尽管是最后定义的,但仍打印在中间。【参考方案2】:
您可以将字典映射到值数组:
let colors = colorsForColorScheme.map $0.1
闭包从字典中获取一个键值元组并只返回一个值。因此,map 函数会生成一个值数组。
相同代码的可读性更高的版本:
let colors = colorsForColorScheme.map (scheme, color) in
return color
更新
从 Xcode 9.0 开始,可以使用 values
属性访问字典值,该属性符合 Collection
协议:
let colors = colorsForColorScheme.values
通常你只希望它作为一个数组:
let colors = Array(dict.values)
就是这样。
【讨论】:
但实际上这是获取数组的可读方式 let colors = Array(colorsForColorScheme.values) 喜欢这个解决方案 @pjuzeliunas 因为这是这里的最佳答案,我刚刚编辑了 2020 年的最新版本。显然放松、编辑等!欢呼,谢谢!【参考方案3】:使用colorsForColorScheme.map($0.value)
【讨论】:
【参考方案4】:你可以在LazyMapCollection
上创建一个扩展
public extension LazyMapCollection
func toArray() -> [Element]
return Array(self)
colorsForColorSchemes.values.toArray()
或 colorsForColorSchemes.keys.toArray()
【讨论】:
【参考方案5】:首先,从以下语句来看,您的变量(字典)名称似乎是colorsForColorScheme
var colorsForColorScheme: [ColorScheme : UIColor] = ...
当您尝试从colorsForColorSchemes
字典中获取值时-
let colors: [UIColor] = colorsForColorSchemes.values
这应该会给你一个编译时错误。无论如何,我假设您有错字,而您的字典名称是colorsForColorSchemes
。所以,这里是解决方案-
如前所述,由于 swift 中的类型推断属性,您的代码可以推断出 .values
函数返回的类型正在返回 UIColor 数组。但是,Swift 希望是类型安全的,因此当您将值存储在 colors
数组中时,您需要明确定义它。对于 swift 5 及更高版本,现在您可以执行以下操作-
let colors = [UIColor](colorsForColorSchemes.values)
【讨论】:
这是一个非常有趣的解决方案,而且资源不多。你有参考吗?谢谢。【参考方案6】:你也可以使用flatMap
:
let colors = colorsForColorScheme.values.flatMap $0
【讨论】:
【参考方案7】:我发现这是 Swift 5 中最有用的:
colorsForColorSchemes.allValues
请参阅文档 - https://developer.apple.com/documentation/foundation/nsdictionary/1408915-allvalues
【讨论】:
这仅适用于 NS 字典。这只是d.values
。在实践中Array(d.values)
以上是关于Swift Dictionary:将值作为数组获取的主要内容,如果未能解决你的问题,请参考以下文章
Swift4.2~数组和字典(Array, Dictionary)基本类型转换
Swift4 JSONDecoder 期望解码 Dictionary<String, Any> 但找到了一个数组 [重复]
将值附加到数据数组并保存在 Userdefault swift
SWIFT“应解码 Dictionary<String, Any>,但找到了一个数组。”,underlyingError: nil))
无法在 Swift 中解析 JSON。 “应解码 Dictionary<String, Any>,但找到了一个数组。” [复制]