我正在尝试解码以下JSON对象
{
"result":[
{
"rank":12,
"user":{
"name":"bob","age":12
}
},
{
"1":[
{
"name":"bob","age":12
},
{
"name":"tim","age":13
},
{
"name":"tony","age":12
},
{
"name":"greg","age":13
}
]
}
]
}
struct userObject { var name:String var age:Int }
基本上是一个具有两种不同对象类型的JSON数组
{ "rank":12, "user": {userObject} }
和a
“1”:[userObjects]
struct data: Decodable {
rank: Int
user: user
1: [user] <-- this is one area Im stuck
}
提前致谢
答案 0 :(得分:2)
只是为了好玩:
首先,您需要用户的结构以及result
数组中第一个和第二个字典的表示。密钥"1"
已映射到one
struct User : Decodable {
let name : String
let age : Int
}
struct FirstDictionary : Decodable {
let rank : Int
let user : User
}
struct SecondDictionary : Decodable {
let one : [User]
private enum CodingKeys: String, CodingKey { case one = "1" }
}
现在是棘手的部分:
result
的容器为nestedUnkeyedContainer
,因为该对象是一个数组。解码第二个字典并复制值。
struct UserData: Decodable {
let rank : Int
let user : User
let oneUsers : [User]
private enum CodingKeys: String, CodingKey { case result }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
var arrayContainer = try container.nestedUnkeyedContainer(forKey: .result)
let firstDictionary = try arrayContainer.decode(FirstDictionary.self)
rank = firstDictionary.rank
user = firstDictionary.user
let secondDictionary = try arrayContainer.decode(SecondDictionary.self)
oneUsers = secondDictionary.one
}
}
如果此代码优于传统的手册 JSONSerialization
是另一个问题。
答案 1 :(得分:0)
如果你给出了JSON格式,那么你几乎没有运气,因为你很可能不得不将你的数组解析为[Any]
,这显然不是很有用。另一方面,如果你能够修改JSON的格式,你应该从另一个方向开始。定义所需的Swift对象并使用JSONEncoder.encode(...)
对其进行编码,以便快速确定JSON的外观,以便以尽可能类型的方式对其进行解析。
这种方法很容易将JSON处理代码减半,因为您的Web服务协议最终会更好地构建。这可能会改善整个系统的结构,因为它将产生更稳定的通信协议。
可悲的是,当事情变得混乱时,这种方法并不总是可行的。根据您的示例,您将能够将代码解析为
let st = """
{
"result":[
{
"rank":12,
"user":{
"name":"bob",
"age":12
}
},
{
"1":[
{
"name":"bob","age":12
},
{
"name":"tim","age":13
},
{
"name":"tony","age":12
},
{
"name":"greg","age":13
}
]
}
]
}
"""
let jsonData1 = st.data(using: .utf8)!
let arbitrary = try JSONSerialization.jsonObject(with: jsonData1, options: .mutableContainers)
这将允许您使用
中的一堆演员表来访问您的数据let dict = arbitrary as! NSDictionary
print(dict["result"])
你明白了。不太有用,因为您非常希望使用{/ 1}}协议,如
Codable
不幸的是,这不起作用,因为 struct ArrayRes : Codable {
let result : [[String:Any]]
}
let decoder1 = JSONDecoder()
do {
let addrRes = try decoder.decode(ArrayRes.self, from: jsonData1)
print(addrRes)
} catch {
print("error on decode: \(error.localizedDescription)")
}
不是Any
,原因有点明显。
我希望你能够改变你的JSON协议,因为当前的JSON协议将成为许多凌乱代码的根本原因。
答案 2 :(得分:-1)
你必须像这样反序列化Json
INSERT
然后你需要向程序显示如何设置这样的数据。
from pymysql.cursors import *
import pymysql
from collections import OrderedDict
import datetime
class OrderedDictCursor(DictCursorMixin, Cursor):
dict_type = OrderedDict
conn1 = pymysql.connect(host='127.0.0.1',
port=3306,
user='root',
passwd='pwd',
db='test',
charset='utf8',
use_unicode=True,
autocommit=True)
cursor1 = conn1.cursor(OrderedDictCursor)
odict = OrderedDict([(u'id', 374), (u'title', u'Chapter 4'), (u'intro_list', u'Objective:\r\n\r\n* Exit any mininet launch done earlier using \u201cmn \u2013c\u201d\r\n'), (u'solution', u'%%beginpanel%%\r\n\r\n## 1. net\r\n\r\n```\r\nmn -c\r\n```\r\n\r\n \u201cCTRL+C\u201d \r\n\r\n%%endpanel%%\r\n'), (u'created', datetime.datetime(2017, 3, 9, 7, 58, 7)), (u'modified', datetime.datetime(2017, 8, 28, 4, 58, 15))])
cols = odict.keys()
vals = odict.values()
cursor1.execute("INSERT INTO %s (%s) VALUES (%s)" % ("test1", ",".join(cols), (str(vals)[1:-1])))
然后根据你有多少jsonobjects你应该循环遍历它们,当你完成它时,你应该将项目发送到一个func,如果你在一个对象中将它们放在你自己的类中。 ps当你在显示程序如何设置Json对象时,你可以通过项目对象作为字典,因为我在第二个codebit中显示你。