0

I have an array of object, each object contains a discount rate , I need to sort them increasingly by their rate,

struct ShopDetails {
    var shopId: Int?
    var discountRate: String?
    init(with json: Dictionary<String,Any>) {
        shopId = json["id"] as? Int
        discountRate = json["discount"] as? String

    }

I tired to sort them using this method;

 func getShopsByDiscount() {
        let sortedImages = self.copyOfShops.sorted(by: { (shop1: ShopDetails, shop2: ShopDetails) -> Bool in
            return Int(shop1.discountRate) < Int(shop2.discountRate)
        })

    }

I tried to cast the rate to integer, since its been received form the backend as string, but I got an error: value of type Any has no member discountRate. any idea how to do it? if there is a way to do it without casting it will be better

9
  • Is there a typo somewhere? The error message has a lowercase discountrate where your code has discountRate. Commented Jan 30, 2018 at 19:03
  • edited please check Commented Jan 30, 2018 at 19:04
  • What is copyOfShops? It's supposed to be [ShopDetails] – which avoids the error by the way – but I guess it's NSArray Commented Jan 30, 2018 at 19:05
  • its the array which contains the objects which I want to sort, its an array of shops Commented Jan 30, 2018 at 19:07
  • 1
    And why is discountRate an (optional) string? Make it a Double and save the trouble! Commented Jan 30, 2018 at 19:13

1 Answer 1

2

First, you need to verify that the array you're starting with is of type [ShopDetails]. The error indicates that this is probably an Objective-C NSArray, which won't work as well in Swift. If you're unclear about this, I suggest you Google the topic: there's no reason to use NSArray in Swift.

Below, I assume the array is the correct type ([ShopDetails]). From here, you need to do two additional things, because discountRate is of type String?.

  1. You need to check if the string is actually there
  2. You need to check if it can actually be expressed as an Int.

With these things in mind, your sort function can look like this:

let sortedImages = copyOfShops.sorted(by: {
    (shop1: ShopDetails, shop2: ShopDetails) -> Bool in
    if let shop1String = shop1.discountRate, let shop1Value = Int(shop1String),
        let shop2String = shop2.discountRate, let shop2Value = Int(shop2String) {
        return shop1Value < shop2Value
    }
    return true
})

That being said, the best way to handle this is to change the type of discountRate from String? to Int, and do the above checks when you init(with json: Dictionary<String,Any>). If the server giving you the dictionary is something you control, have it switch to passing back Ints instead of Strings, and stop dealing with optionals if you don't have to.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.