如何在上一级数据的基础上获取数据



我有如下JSON。

{
"type": "regular",
"data": [
{
"title": "Title 1",
"price_regular": 1.1,
"price_express": 2.2,
},
{
"title": "Title 2",
"price_regular": 1.1,
"price_express": 2.2,
}
]
}

为此,我有如下模型。

struct MainModel : Codable {
var type : String?
var data : [DataModel]?
}
struct DataModel : Codable {
var title : String?
var price_regular : Float?
var price_express : Float?

var price : Float {
get {
if (type == "regular") { ----> Please check below query for this.
return price_regular ?? 0.0
}

return price_express ?? 0.0
}
}
}

我在DataModel中所做的是将新变量创建为price。我想检查我对主类的type有什么数据,基于此,我想获得Price的值。我有办法做到这一点吗?

事实上,我是在玩模特。我知道我可以使这个运行时,但我想在模型中这样做,这样逻辑只在1个位置。

我会用一个自定义的init(from decoder:)来完成,允许将类型从MainModel传递到DataModel

struct MainModel : Codable {
var type : String?
var data : [DataModel]?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
type = try container.decode(String.self, forKey: .type)
var dataContainer = try container.nestedUnkeyedContainer(forKey: .data)
var dataTemp: [DataModel] = []
while !dataContainer.isAtEnd {
let dataSubcontainer = try dataContainer.nestedContainer(keyedBy: DataModel.DataModelKeys.self)
let title = try dataSubcontainer.decode(String.self, forKey: .title)
let price_regular = try dataSubcontainer.decode(Float.self, forKey: .price_regular)
let price_express = try dataSubcontainer.decode(Float.self, forKey: .price_express)
dataTemp.append(DataModel(title: title, price_regular: price_regular, price_express: price_express, type: type))
}
data = dataTemp
}
}
struct DataModel : Codable {
var title : String?
var price_regular : Float?
var price_express : Float?
var type: String?
enum DataModelKeys: String, CodingKey {
case title
case price_regular
case price_express
}
var price : Float {
get {
if (type == "regular") {
return price_regular ?? 0.0
}
return price_express ?? 0.0
}
}
}

测试:

let json = """
[{
"type": "regular",
"data": [
{
"title": "Title 1",
"price_regular": 1.1,
"price_express": 1.2,
},
{
"title": "Title 2",
"price_regular": 2.1,
"price_express": 2.2,
}
]
},
{
"type": "irregular",
"data": [
{
"title": "Title 3",
"price_regular": 1.1,
"price_express": 1.2,
},
{
"title": "Title 4",
"price_regular": 2.1,
"price_express": 2.2,
}
]
}]
"""
do {
let model = try JSONDecoder().decode([MainModel].self, from: Data(json.utf8))
print(model)
model.forEach { aMainModel in
print("MainModel type: (aMainModel.type)")
aMainModel.data?.forEach {
print("Title: ($0.title) - type: ($0.type) - price: ($0.price)")
}
}
} catch {
print("Error: (error)")
}

哪个输出:

$>MainModel type: Optional("regular")
$>Title: Optional("Title 1") - type: Optional("regular") - price: 1.1
$>Title: Optional("Title 2") - type: Optional("regular") - price: 2.1
$>MainModel type: Optional("irregular")
$>Title: Optional("Title 3") - type: Optional("irregular") - price: 1.2
$>Title: Optional("Title 4") - type: Optional("irregular") - price: 2.2

在@Larme answer的帮助下,我更新了模型并使其正常工作。

struct MainModel : Codable {
var type : String?
var data : [DataModel]? {
didSet { // on didSet assigned value of type to type
for i in 0..<(self.data ?? [DataModel]()).count {
self.data![i].type = self.type ?? ""
}
}
}


}
struct DataModel : Codable {
var title : String?
var price_regular : Float?
var price_express : Float?

var type : String? // added new variable

var price : Float? {
get {
if (type == "regular") {
return price_regular ?? 0.0
}
return price_express ?? 0.0
}
}
}

这帮助我做了我想要做的事。。。

最新更新