如何处理nil值变量 [英] how to handle the nil value variables
问题描述
我的模型如下.
struc Info: Decodable {
var firstName: String?
var lastName: String?
}
在表格单元格中显示时,我正在做的事情如下.
While displaying in tableview cell, what I am doing is as below.
personName.text = "\(personArray[indexPath.row].firstName!) \(personArray[indexPath.row].lastName!)"
如果我具有以下格式的数据,则应用程序现在崩溃
Now the app is crashing if I have data in below format
[
{
"firstName" : "F 1",
"lastName" : "L 1"
},
{
"firstName" : "F 2"
},
{
"lastName" : "L 3"
}
]
应用程序崩溃,说姓氏为空
The app is crashing saying lastName is nil
此检查为nil&的解决方案然后显示名称,但是我不想在运行时进行检查,因为 我必须检查所有变量(考虑到我有25个变量的模型) .下面是我可以做的.
The solution for this check for nil & then show name, however I don't want to do the check at run time because that I have to check this for all variables (considering I have model of 25 variables). Below is what I could have done.
var firstName = ""
if (personArray[indexPath.row].firstName == nil) {
firstName = ""
} else {
firstName = personArray[indexPath.row].firstName!
}
var lastName = ""
if (personArray[indexPath.row].lastName == nil) {
lastName = ""
} else {
lastName = personArray[indexPath.row].lastName!
}
personName.text = "\(firstName) \(lastName)"
解决方案2
我可以在模型本身中进行如下更新.
Solution 2
I can do the update in the model itself as below.
struc Info: Decodable {
var firstName: String?
var lastName: String?
var firstName2 : String? {
get {
if (self.firstName==nil) {
return ""
}
return firstName
}
var lastName2 : String? {
get {
if (self.lastName==nil) {
return ""
}
return lastName
}
}
personName.text = "\(personArray[indexPath.row].firstName2!) \(personArray[indexPath.row].lastName2!)"
但是我对此也有疑问.这样, 我必须再次创建N个变量.
However I have problem with this also. This way, again I have to create N number of variables again.
如果Web服务中缺少该变量,还有其他替代方法可以分配默认值吗?
Is there any other alternate way where default value will get assigned if that variable is missing in the webservice?
推荐答案
我建议使用以下两种方法之一:
I would recommend one of two options:
- 将计算的属性添加到结构中以确定显示名称.
- 手动解码,提供默认值. (如果需要,还可以添加显示名称属性)
我个人喜欢选项1.我认为它是最紧凑且最容易维护的.
Personally, I like option 1. I think it's the most compact and also the easiest to maintain.
选项1示例:
struct Info1: Decodable {
var firstName: String?
var lastName: String?
var displayName: String {
return [self.firstName, self.lastName]
.compactMap { $0 } // Ignore 'nil'
.joined(separator: " ") // Combine with a space
}
}
print(Info1(firstName: "John", lastName: "Smith").displayName)
// Output: "John Smith"
print(Info1(firstName: "John", lastName: nil).displayName)
// Output: "John"
print(Info1(firstName: nil, lastName: "Smith").displayName)
// Output: "Smith"
print(Info1(firstName: nil, lastName: nil).displayName)
// Output: ""
选项2示例:
struct Info2: Decodable {
var firstName: String
var lastName: String
enum CodingKeys: String, CodingKey {
case firstName, lastName
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.firstName = try container.decodeIfPresent(String.self, forKey: .firstName) ?? ""
self.lastName = try container.decodeIfPresent(String.self, forKey: .lastName) ?? ""
}
// Optional:
var displayName: String {
return [self.firstName, self.lastName]
.compactMap { $0.isEmpty ? nil : $0 } // Ignore empty strings
.joined(separator: " ") // Combine with a space
}
// TEST:
init(from dict: [String: Any]) {
let data = try! JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
self = try! JSONDecoder().decode(Info2.self, from: data)
}
}
print(Info2(from: ["firstName": "John", "lastName": "Smith"]).displayName)
// Output: "John Smith"
print(Info2(from: ["lastName": "Smith"]).displayName)
// Output: "Smith"
print(Info2(from: ["firstName": "John"]).displayName)
// Output: "John"
print(Info2(from: [String: Any]()).displayName)
// Output: ""
这篇关于如何处理nil值变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!