如何使用 swift codable 根据特定排序顺序对自定义对象进行排序
How to sort custom objects according to a specific sort order using swift codable
如何根据特定排序顺序对自定义对象 swift codable 进行排序。
我正在使用 swift 可编码协议。
{
"data": {
"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"recruiterName": "Lorium Ipsem text",
"respondsQuickly": "1"
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
这里我需要根据sortOrder对象对数据对象进行排序。
现在这是一个模型对象
struct Welcome: Codable {
let data: DataClass?
let metaData: MetaData?
}
struct JDDataClass: Codable {
let team: [Team]?
let recruiterName, respondsQuickly: String?
}
struct Team: Codable {
let name, designation: String?
}
struct JDMetaData: Codable {
let sortOrder: [String]?
}
我找不到All Keys也作为它的模型。
它现在不是 JSON 或字典,因为它是 Codabale 协议的自定义对象 swift。
期望的输出:
let myArray = [
{"respondsQuickly": "1"},
{"recruiterName": "Lorium Ipsem text"},
{"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
]
}
]
按结构键排序没有任何意义。当访问每个元素的成本相同时为什么要对对象的变量进行排序。
可能您当前的结构有误。
{
"data": {
"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"recruiterName": "Lorium Ipsem text",
"respondsQuickly": "1"
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
如果您希望上述输出具有如下结构,这会更有意义:
{
"data": {
"keys": [
"team",
"recruiterName",
"respondsQuickly"
],
"values": [
[
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"Lorium Ipsem text",
"1"
]
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
不过,如果您想使用当前结构实现此输出,您可以使用类似以下内容的方法:Reflection 在运行时读取结构的属性并相应地对其进行排序。不用说,这个解决方案很丑陋,应该避免。
这是可用的 playground 代码。你可以检查一下。我希望这将有所帮助。 arrResult 正在保存你的答案。
struct Welcome: Codable {
let data: JDDataClass?
let metaData: JDMetaData?
}
struct JDDataClass: Codable {
let team: [Team]?
let recruiterName, respondsQuickly: String?
}
struct Team: Codable {
let name, designation: String?
}
struct JDMetaData: Codable {
let sortOrder: [String]?
}
let multiLineString = """
{
"data": {
"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"recruiterName": "Lorium Ipsem text",
"respondsQuickly": "1"
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
"""
extension Encodable {
subscript(key: String) -> Any? {
return dictionary[key]
}
var dictionary: [String: Any] {
return (try? JSONSerialization.jsonObject(with: JSONEncoder().encode(self))) as? [String: Any] ?? [:]
}
}
let decoder = JSONDecoder()
do {
if let data = multiLineString.data(using: String.Encoding.utf8, allowLossyConversion: false){
let json = try decoder.decode(Welcome.self, from: data)
var arrResult = [[String : Any]]()
if let sortOrder = json.metaData?.sortOrder {
for item in sortOrder {
if let data = json.data {
if let obj = data[item] {
arrResult.append([item: obj])
}
}
}
print(arrResult)
}
}
} catch {
print(error)
}
如何根据特定排序顺序对自定义对象 swift codable 进行排序。 我正在使用 swift 可编码协议。
{
"data": {
"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"recruiterName": "Lorium Ipsem text",
"respondsQuickly": "1"
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
这里我需要根据sortOrder对象对数据对象进行排序。 现在这是一个模型对象
struct Welcome: Codable {
let data: DataClass?
let metaData: MetaData?
}
struct JDDataClass: Codable {
let team: [Team]?
let recruiterName, respondsQuickly: String?
}
struct Team: Codable {
let name, designation: String?
}
struct JDMetaData: Codable {
let sortOrder: [String]?
}
我找不到All Keys也作为它的模型。 它现在不是 JSON 或字典,因为它是 Codabale 协议的自定义对象 swift。
期望的输出:
let myArray = [
{"respondsQuickly": "1"},
{"recruiterName": "Lorium Ipsem text"},
{"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
]
}
]
按结构键排序没有任何意义。当访问每个元素的成本相同时为什么要对对象的变量进行排序。
可能您当前的结构有误。
{
"data": {
"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"recruiterName": "Lorium Ipsem text",
"respondsQuickly": "1"
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
如果您希望上述输出具有如下结构,这会更有意义:
{
"data": {
"keys": [
"team",
"recruiterName",
"respondsQuickly"
],
"values": [
[
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"Lorium Ipsem text",
"1"
]
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
不过,如果您想使用当前结构实现此输出,您可以使用类似以下内容的方法:Reflection 在运行时读取结构的属性并相应地对其进行排序。不用说,这个解决方案很丑陋,应该避免。
这是可用的 playground 代码。你可以检查一下。我希望这将有所帮助。 arrResult 正在保存你的答案。
struct Welcome: Codable {
let data: JDDataClass?
let metaData: JDMetaData?
}
struct JDDataClass: Codable {
let team: [Team]?
let recruiterName, respondsQuickly: String?
}
struct Team: Codable {
let name, designation: String?
}
struct JDMetaData: Codable {
let sortOrder: [String]?
}
let multiLineString = """
{
"data": {
"team": [
{
"name": "XYZ",
"designation": "Managing director - South Asia"
},
{
"name": "XYZ",
"designation": "Managing director - South Asia"
}
],
"recruiterName": "Lorium Ipsem text",
"respondsQuickly": "1"
},
"metaData": {
"sortOrder": [
"respondsQuickly",
"recruiterName",
"team"
]
}
}
"""
extension Encodable {
subscript(key: String) -> Any? {
return dictionary[key]
}
var dictionary: [String: Any] {
return (try? JSONSerialization.jsonObject(with: JSONEncoder().encode(self))) as? [String: Any] ?? [:]
}
}
let decoder = JSONDecoder()
do {
if let data = multiLineString.data(using: String.Encoding.utf8, allowLossyConversion: false){
let json = try decoder.decode(Welcome.self, from: data)
var arrResult = [[String : Any]]()
if let sortOrder = json.metaData?.sortOrder {
for item in sortOrder {
if let data = json.data {
if let obj = data[item] {
arrResult.append([item: obj])
}
}
}
print(arrResult)
}
}
} catch {
print(error)
}