如何使用 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)
 }