从检查nil值的结构中优雅地填充字典 [英] Elegantly populate dictionary from a struct checking nil values

查看:81
本文介绍了从检查nil值的结构中优雅地填充字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个结构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.

或者,您可以跳过pairsArrayDictionaryLiteral,而直接直接分配值:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆