从检查nil值的结构中优雅地填充字典 [英] Elegantly populate dictionary from a struct checking nil values
问题描述
给出一个结构A
,我想用该结构中的值填充NSDictionary
,只要它们不是nil.
为此,我插入所有值,然后遍历字典,删除所有nil
.有没有更优雅,简洁,更少暴力的解决方案?
Given a struct A
, I want to populate a NSDictionary
with values from that struct, provided they are not nil.
To do that I insert all the values and then loop through the dictionary removing all nil
. Is there a more elegant, concise, and less brute-force solution?
struct A {
var first:String?
var second:String?
var third:String?
/* some init */
}
let a = A(/*some init*/)
var dictionary = [
"first":a.first,
"second":a.second,
"third":a.third
]
for (key,value) in dictionary {
if value == nil {
dictionary.removeValue(forKey: key)
}
}
推荐答案
拥有一个可选值的字典通常不是一个好主意.词典使用nil
的分配指示您要从词典中删除键/值对.另外,字典查找返回一个可选值,因此,如果您的值是可选的,那么最终将得到一个double可选的东西,需要将其解包两次.
It's usually not a good idea to have a dictionary with a value that is optional. Dictionaries use the assignment of nil
as an indication that you want to delete a key/value pair from the dictionary. Also, dictionary lookups return an optional value, so if your value is optional you will end up with a double optional that needs to be unwrapped twice.
您可以使用以下事实:分配nil
会通过仅分配值来删除字典条目以构建[String : String]
字典. nil
的那些将不会进入字典,因此您不必删除它们:
You can use the fact that assigning nil
deletes a dictionary entry to build up a [String : String]
dictionary by just assigning the values. The ones that are nil
will not go into the dictionary so you won't have to remove them:
struct A {
var first: String?
var second: String?
var third: String?
}
let a = A(first: "one", second: nil, third: "three")
let pairs: [(String, String?)] = [
("first", a.first),
("second", a.second),
("third", a.third)
]
var dictionary = [String : String]()
for (key, value) in pairs {
dictionary[key] = value
}
print(dictionary)
["third": "three", "first": "one"]
正如@Hamish在注释中指出的那样,您可以对pairs
使用DictionaryLiteral
(内部只是一个元组数组),它允许您使用更简洁的字典语法:
As @Hamish noted in the comments, you can use a DictionaryLiteral
(which internally is just an array of tuples) for pairs
which allows you to use the cleaner dictionary syntax:
let pairs: DictionaryLiteral<String,String?> = [
"first": a.first,
"second": a.second,
"third": a.third
]
所有其他代码保持不变.
All of the other code remains the same.
注意:您可以编写DictionaryLiteral
并让编译器推断类型,但是我已经看到Swift无法对大型字典文字进行编译或编译速度非常慢.这就是为什么我在这里显示了显式类型的原因.
Note: You can just write DictionaryLiteral
and let the compiler infer the types, but I have seen Swift fail to compile or compile very slowly for large dictionary literals. That is why I have shown the use of explicit types here.
或者,您可以跳过pairs
的Array
或DictionaryLiteral
,而直接直接分配值:
Alternatively, you can skip the Array
or DictionaryLiteral
of pairs
and just assign the values directly:
struct A {
var first: String?
var second: String?
var third: String?
}
let a = A(first: "one", second: nil, third: "three")
var dictionary = [String : String]()
dictionary["first"] = a.first
dictionary["second"] = a.second
dictionary["third"] = a.third
print(dictionary)
["third": "three", "first": "one"]
这篇关于从检查nil值的结构中优雅地填充字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!