如何使用快速编码根据特定的排序顺序对自定义对象进行排序

Posted

技术标签:

【中文标题】如何使用快速编码根据特定的排序顺序对自定义对象进行排序【英文标题】:How to sort custom objects according to a specific sort order using swift codable 【发布时间】:2019-01-07 17:30:23 【问题描述】:

如何根据特定的排序顺序对自定义对象进行快速编码。 我正在使用 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"
              
            ]
        
    ]

【问题讨论】:

您的 json 无效,请发布正确的 json 消息。我假设 JDDataClass 也是数组的一部分,否则在 recruiterNamefor instance 上进行排序是没有意义的 请澄清您的问题。你上一个代码例子看不懂,responseDTO是什么data是什么,你为什么要给一个字符串分配一个int? @JoakimDanielson 完成更改 这没有任何意义。 "data" 键中的值是 Dictionary,但您想将其转换为 Array,这对我的理解没有任何用处。 【参考方案1】:

这是运行的游乐场代码。你可以检查一下。我希望这将有所帮助。 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)
 

【讨论】:

【参考方案2】:

按结构键排序没有任何意义。当访问每个元素的成本相同时,为什么要对对象的变量进行排序。

也许你当前的结构是错误的。


  "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 在运行时读取结构的属性并相应地对其进行排序。不用说,这种解决方案很丑陋,应该避免。

【讨论】:

以上是关于如何使用快速编码根据特定的排序顺序对自定义对象进行排序的主要内容,如果未能解决你的问题,请参考以下文章

按属性对自定义对象的 ArrayList 进行排序

在Objective-C中按一个属性对自定义对象的NSSet进行排序

使用内部对象的实例变量的值对自定义对象数组进行排序

如何使用 NSKeyedArchiver 对自定义类进行编码和解码

是否可以根据这些对象的参数对自定义类对象列表进行子集化? (没有 LINQ)

C#根据多个(26 + 3)类别以特定顺序对对象列表进行排序(LINQ,if else,switch case)[关闭]