【问题标题】:Sort an Array of objects in swift快速排序对象数组
【发布时间】:2021-06-15 17:06:59
【问题描述】:

我知道排序方法,但我现在的情况有所不同,所以我问这个。

如果对象是直接的没问题,我可以按此代码排序

self.filterArray = self.valuesArray.sorted(by: {  $0.firstname! <  $1.firstname! })

我的 json 对象:

[
{

            "loan_amt": "729442",
            "combine_sc_details": "{\"dp_sc\": 560000, \"ltv_sc\": 315000, \"roi_sc\": 15.53, \"vwBand\": \"-\", \"vwScore\": 0, \"dp_per_sc\": 64, \"tenure_sc\": \"60\", \"veh_offer\": \"no offer\", \"kuwy_score\": \"-1\", \"ltv_per_sc\": 36, \"loanProduct\": \"LP2\", \"multi_score\": \"-1\", \"decision_str\": \"SUBJECT TO DETALIED REVIEW\", \"product_band\": \"-\", \"experianScore\": 0, \"score_band_str\": \"S9\", \"subventionType\": 0, \"combined_score_int\": \"675\"}",
            "firstname": "HARIPRASANTH",

        },
        {
            "loan_amt": "729442",
            "combine_sc_details": "{\"dp_sc\": 715000, \"ltv_sc\": 160000, \"roi_sc\": 15.53, \"vwBand\": \"-\", \"vwScore\": 0, \"dp_per_sc\": 81.71428571428572, \"tenure_sc\": \"60\", \"veh_offer\": \"no offer\", \"kuwy_score\": \"-1\", \"ltv_per_sc\": 18.285714285714285, \"loanProduct\": \"LP2\", \"multi_score\": \"-1\", \"decision_str\": \"SUBJECT TO DETALIED REVIEW\", \"product_band\": \"-\", \"experianScore\": 0, \"score_band_str\": \"S9\", \"subventionType\": 0, \"combined_score_int\": \"675\"}",
            "firstname": "Naveen kumar",
           
        },
        {
            "loan_amt": "207954",
            "combine_sc_details": "{\"emi\": 7308, \"dp_sc\": 31046, \"ltv_sc\": 249545, \"roi_sc\": 17.83, \"vwBand\": \"-\", \"vwScore\": 0, \"raccRate\": 17.83, \"dp_per_sc\": 12.989958158995815, \"tenure_sc\": 48, \"veh_offer\": \"NO OFFER\", \"kuwy_score\": \"-1\", \"ltv_per_sc\": 100, \"loanProduct\": \"LP2\", \"multi_score\": \"-1\", \"decision_str\": \"SUBJECT TO DETALIED REVIEW\", \"exshow_price\": \"249545\", \"product_band\": \"-\", \"experianScore\": 0, \"roiSubvention\": 0, \"vehi_discount\": \"\", \"score_band_str\": \"S8\", \"sub_ven_Column\": \"STANDARD LOAN PRODUCTS\", \"subventionType\": 1, \"combined_score_int\": \"700\"}",
           
            "firstname": "KARTHIK",
            
        }
]

我可以使用 firstname 的键进行过滤,其中 combine_sc_details 是 String 类型 如何根据 combine_sc_details 中的 ltv_sc 进行过滤。

我已经将 Struct 写到 combine_sc_details

struct CombinedScoreResponse : Decodable {
    let dealer_payout : String?
    let vehi_discount : String?
    let emi : Int?
    let exshow_price : String?
    let raccRate : Double?
//    let tenure_sc : Int?
    let tenure_sc : QuantumValue?//Changes
    let kuwy_score : String?
    let discount_dp : String?
    let combined_score_int : String?
//    let dp_sc : Int?
    let dp_sc : QuantumValue?//Changes
    let loanProduct : String?
//    let dp_per_sc : Int?
    let dp_per_sc : QuantumValue?//Changes
    let vwBand : String?
    let decision_str : String?
    let vwScore : Int?
    let experianScore : Int?
//    let ltv_sc : Int?
    let ltv_sc : QuantumValue?//Changes
    let veh_offer : String?
    let sub_ven_Column : String?
    let score_band_str : String?
    let multi_score : String?
    let subventionType : Int?
    let roiSubvention : Int?
    let product_band : String?
    let roi_sc : Double?
//    let ltv_per_sc : Int?
    let ltv_per_sc : QuantumValue?//Changes
    
    let rvKms : Int?
    let rvValue : Double?
    

    
    enum CodingKeys: String, CodingKey {

        case rvKms = "rvKms"
        case rvValue = "rvValue"
        
        case dealer_payout = "dealer_payout"
        case vehi_discount = "vehi_discount"
        case emi = "emi"
        case exshow_price = "exshow_price"
        case raccRate = "raccRate"
        case tenure_sc = "tenure_sc"
        case kuwy_score = "kuwy_score"
        case discount_dp = "discount_dp"
        case combined_score_int = "combined_score_int"
        case dp_sc = "dp_sc"
        case loanProduct = "loanProduct"
        case dp_per_sc = "dp_per_sc"
        case vwBand = "vwBand"
        case decision_str = "decision_str"
        case vwScore = "vwScore"
        case experianScore = "experianScore"
        case ltv_sc = "ltv_sc"
        case veh_offer = "veh_offer"
        case sub_ven_Column = "sub_ven_Column"
        case score_band_str = "score_band_str"
        case multi_score = "multi_score"
        case subventionType = "subventionType"
        case roiSubvention = "roiSubvention"
        case product_band = "product_band"
        case roi_sc = "roi_sc"
        case ltv_per_sc = "ltv_per_sc"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        dealer_payout = try values.decodeIfPresent(String.self, forKey: .dealer_payout)
        vehi_discount = try values.decodeIfPresent(String.self, forKey: .vehi_discount)
        emi = try values.decodeIfPresent(Int.self, forKey: .emi)
        exshow_price = try values.decodeIfPresent(String.self, forKey: .exshow_price)
        raccRate = try values.decodeIfPresent(Double.self, forKey: .raccRate)
        tenure_sc = try values.decodeIfPresent(QuantumValue.self, forKey: .tenure_sc)
        kuwy_score = try values.decodeIfPresent(String.self, forKey: .kuwy_score)
        discount_dp = try values.decodeIfPresent(String.self, forKey: .discount_dp)
        combined_score_int = try values.decodeIfPresent(String.self, forKey: .combined_score_int)
        dp_sc = try values.decodeIfPresent(QuantumValue.self, forKey: .dp_sc)
        loanProduct = try values.decodeIfPresent(String.self, forKey: .loanProduct)
        dp_per_sc = try values.decodeIfPresent(QuantumValue.self, forKey: .dp_per_sc)
        vwBand = try values.decodeIfPresent(String.self, forKey: .vwBand)
        decision_str = try values.decodeIfPresent(String.self, forKey: .decision_str)
        vwScore = try values.decodeIfPresent(Int.self, forKey: .vwScore)
        experianScore = try values.decodeIfPresent(Int.self, forKey: .experianScore)
        ltv_sc = try values.decodeIfPresent(QuantumValue.self, forKey: .ltv_sc)
        veh_offer = try values.decodeIfPresent(String.self, forKey: .veh_offer)
        sub_ven_Column = try values.decodeIfPresent(String.self, forKey: .sub_ven_Column)
        score_band_str = try values.decodeIfPresent(String.self, forKey: .score_band_str)
        multi_score = try values.decodeIfPresent(String.self, forKey: .multi_score)
        subventionType = try values.decodeIfPresent(Int.self, forKey: .subventionType)
        roiSubvention = try values.decodeIfPresent(Int.self, forKey: .roiSubvention)
        product_band = try values.decodeIfPresent(String.self, forKey: .product_band)
        roi_sc = try values.decodeIfPresent(Double.self, forKey: .roi_sc)
        ltv_per_sc = try values.decodeIfPresent(QuantumValue.self, forKey: .ltv_per_sc)
        
        rvKms = try values.decodeIfPresent(Int.self, forKey: .rvKms)
        rvValue = try values.decodeIfPresent(Double.self, forKey: .rvValue)
    }

}

我们在下面访问这些值

if let combine_sc_details = currentLoanInfo.combine_sc_details{
            print("Combined Score ===> ", combine_sc_details)
            let data = Data(combine_sc_details.utf8)
            let decoder = JSONDecoder()
            do {
                let loc = try decoder.decode(CombinedScoreResponse.self, from: data)
                
                if let subType = loc.ltv_sc{
                }
                
               
            }catch{
                print("Parsing error")
            }
        }

在这里,我们正在努力在下面的部分中应用逻辑

 self.filterArray = self.valuesArray.sorted(by: {  //Confusing here ??????? })

【问题讨论】:

  • 您是否首先将 JSON 解析为自定义结构?那将是一个好的开始。您想排序(定义顺序)还是过滤(只保留想要的)?不清楚。
  • 您必须在第二级解码嵌套的 JSON 字符串(combine_sc_details 的值)才能过滤某些内容。发送嵌套的 JSON 非常不方便。
  • @vadian 检查我更新的任务,还有吗?
  • @Larme 检查我更新的任务
  • $0.combine_sc_details.ltv_sc &lt; $1.combine_sc_details.ltv_sc,或者类似的?

标签: ios arrays swift sorting


【解决方案1】:

解析上面的json后,会得到以下2个模型。

struct MainModel : Codable {
    let loan_amt : String?
    let combine_sc_details : CombineSCDetails?
    let firstname : String?

    enum CodingKeys: String, CodingKey {

        case loan_amt = "loan_amt"
        case combine_sc_details = "combine_sc_details"
        case firstname = "firstname"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        loan_amt = try values.decodeIfPresent(String.self, forKey: .loan_amt)
        do {
            if let jsonString = try values.decodeIfPresent(String.self, forKey: .combine_sc_details) {
            let data: Data? = jsonString?.data(using: .utf8)
            combine_sc_details = try JSONDecoder().decode(CombineSCDetails.self, from: data)
        }
        } catch {
            combine_sc_details = nil
        }
        firstname = try values.decodeIfPresent(String.self, forKey: .firstname)
    }
}


struct CombineSCDetails : Codable {
    let dp_sc : Int?
    let ltv_sc : Int?
    let roi_sc : Double?
    let vwBand : String?
    let vwScore : Int?
    let dp_per_sc : Int?
    let tenure_sc : String?
    let veh_offer : String?
    let kuwy_score : String?
    let ltv_per_sc : Int?
    let loanProduct : String?
    let multi_score : String?
    let decision_str : String?
    let product_band : String?
    let experianScore : Int?
    let score_band_str : String?
    let subventionType : Int?
    let combined_score_int : String?

    enum CodingKeys: String, CodingKey {

        case dp_sc = "dp_sc"
        case ltv_sc = "ltv_sc"
        case roi_sc = "roi_sc"
        case vwBand = "vwBand"
        case vwScore = "vwScore"
        case dp_per_sc = "dp_per_sc"
        case tenure_sc = "tenure_sc"
        case veh_offer = "veh_offer"
        case kuwy_score = "kuwy_score"
        case ltv_per_sc = "ltv_per_sc"
        case loanProduct = "loanProduct"
        case multi_score = "multi_score"
        case decision_str = "decision_str"
        case product_band = "product_band"
        case experianScore = "experianScore"
        case score_band_str = "score_band_str"
        case subventionType = "subventionType"
        case combined_score_int = "combined_score_int"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        dp_sc = try values.decodeIfPresent(Int.self, forKey: .dp_sc)
        ltv_sc = try values.decodeIfPresent(Int.self, forKey: .ltv_sc)
        roi_sc = try values.decodeIfPresent(Double.self, forKey: .roi_sc)
        vwBand = try values.decodeIfPresent(String.self, forKey: .vwBand)
        vwScore = try values.decodeIfPresent(Int.self, forKey: .vwScore)
        dp_per_sc = try values.decodeIfPresent(Int.self, forKey: .dp_per_sc)
        tenure_sc = try values.decodeIfPresent(String.self, forKey: .tenure_sc)
        veh_offer = try values.decodeIfPresent(String.self, forKey: .veh_offer)
        kuwy_score = try values.decodeIfPresent(String.self, forKey: .kuwy_score)
        ltv_per_sc = try values.decodeIfPresent(Int.self, forKey: .ltv_per_sc)
        loanProduct = try values.decodeIfPresent(String.self, forKey: .loanProduct)
        multi_score = try values.decodeIfPresent(String.self, forKey: .multi_score)
        decision_str = try values.decodeIfPresent(String.self, forKey: .decision_str)
        product_band = try values.decodeIfPresent(String.self, forKey: .product_band)
        experianScore = try values.decodeIfPresent(Int.self, forKey: .experianScore)
        score_band_str = try values.decodeIfPresent(String.self, forKey: .score_band_str)
        subventionType = try values.decodeIfPresent(Int.self, forKey: .subventionType)
        combined_score_int = try values.decodeIfPresent(String.self, forKey: .combined_score_int)
    }

}

现在您可以使用代码根据“ltv_sc”的必填字段进行过滤:

self.filterArray = self.valuesArray.sorted(by: {  $0.combine_sc_details?.ltv_sc <  $1.combine_sc_details?.ltv_sc })

【讨论】:

  • 它不在我手中它来自服务器..所以我需要在从服务器获取价值后更新我的模型
  • 以上模型是根据你给@KarthiKeyan的json响应解析出来的,模型的名字可以保留,请理解过程
  • 是的,它会工作,但 combine_sc_details 是来自服务器的字符串类型
  • @KarthiKeyan 这就是我制作另一个模型并将其转换为模型对象的原因。检查代码:这里的关键元素是: if let jsonString = try values.decodeIfPresent(String.self, forKey: .combine_sc_details) let data: Data? = jsonString?.data(using: .utf8) combine_sc_details = try JSONDecoder().decode(CombineSCDetails.self, from: data)
  • @KarthiKeyan 检查 MainModel 的初始化(来自解码器:解码器),看看“combine_sc_details”是如何解析为对象的
猜你喜欢
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 2015-05-01
  • 2015-11-19
  • 1970-01-01
相关资源
最近更新 更多