0

In my json result, there is odds array. And inside of it, there will be 8 types of bet. And i want to sort the array by bet type as i want to show. Eg. first "name": "3Way Result", second another one, third "over/under" etc..

Here is my json result from server.

 {
    "success": true,
    "result": [
        {
            "league_id": 5,
            "localTeam": {"data": {}},
            "visitorTeam": {"data": {}},
            "scores": {},
            "time": {"starting_at": {},},
            "league": {"data": {"coverage": {}}},
            "odds": [
                {
                    "id": 12,
                    "name": "Over/Under",
                    "suspended": false,
                    "bookmaker": {
                        "data": [
                            {
                                "id": 2,
                                "name": "bet365",
                                "odds": {
                                    "data": [
                                        {
                                            "label": "Over",
                                            "value": "2.00",
                                            "extra": null,
                                            "probability": "50%",
                                            "dp3": "2.000",
                                            "american": 100,
                                            "handicap": null,
                                            "total": "2.5",
                                            "winning": null,
                                            "stop": false,
                                            "bookmaker_event_id": 84922729,
                                        },
                                        {
                                            "label": "Under",
                                            "value": "1.80",
                                            "probability": "55.56%",
                                            "dp3": "1.800",

                                        }
                                    ]
                                }
                            }
                        ]
                    }
                },
                {
                    "id": 1,
                    "name": "3Way Result",
                    "suspended": false,
                    "bookmaker": {
                        "data": [
                            {
                                "id": 2,
                                "name": "bet365",
                                "odds": {
                                    "data": [
                                        {
                                            "label": "1",
                                            "value": "2.10",
                                            "extra": null,
                                            "probability": "47.62%",
                                            "dp3": "2.100",
                                            "american": 110,

                                        },
                                        {
                                            "label": "X",
                                            "value": "3.30",
                                            "extra": null,
                                            "probability": "30.3%",
                                            "dp3": "3.300",
                                            "american": 229,

                                        },
                                        {
                                            "label": "2",
                                            "value": "3.60",

                                        }
                                    ]
                                }
                            }
                        ]
                    }
                },
                {
                    "id": 975909,
                    "name": "Correct Score",
                    "suspended": false,
                    "bookmaker": {
                        "data": [
                            {
                                "id": 2,
                                "name": "bet365",
                                "odds": {
                                    "data": [
                                        {
                                            "label": "1:0",
                                            "value": "7.50",
                                            "extra": null,
                                            "probability": "13.33%",
                                            "dp3": "7.500",
                                            "american": 650,
                                            "factional": null,
                                            "handicap": null,
                                            "total": null,
                                            "winning": null,
                                            "stop": false,
                                            "bookmaker_event_id": 84922729,
                                            "last_update": {
                                                "date": "2020-02-20 10:59:06.746514",
                                                "timezone_type": 3,
                                                "timezone": "UTC"
                                            }
                                        },
                                        {
                                            "label": "2:0",
                                            "value": "10.00",

                                        },

                                    ]
                                }
                            }
                        ]
                    }
                },


            ],
            "tipsters": 2
        }
    ]
} 

so it is not alphabetically, datetime or anytype i could access. How could i do ?

Update: I have added model.

struct BetterMatchResults: APIModel, Codable {
    var success: Bool?
    var result: [BetterMatch]?
}
struct BetterMatch: APIModel, Codable  {
    var id,_id: String?
    var localTeam, visitorTeam: BetterTeam?
    var spId, league_id, seasonID: Int?
    var winningOddsCalculated: Bool?
    var time: BetterTime?
    var league: BetterLeague?
    var createdAt, updatedAt: String?
    var odds: [BetterOdd]!
    var resultID: String?
    var tipsters: Int?
    var stats_url: String?
}

struct BetterLeague : APIModel, Codable {
    var data: LeagueData?
}

struct LeagueData : APIModel, Codable{
    var id: Int?
    var active: Bool?
    //var legacyID, countryID: Int?
    var logo_path: String?
    var name: String?
    //var isCup: Bool?

}

struct BetterOdd : APIModel, Codable {
    var id: Int?
    var name: String?
    var suspended: Bool?
    var bookmaker: BetterBookmaker?
   }

// MARK: - Bookmaker
struct BetterBookmaker : APIModel, Codable {
    var data: [BetterBookmakerDatum]?
}

// MARK: - BookmakerDatum
struct BetterBookmakerDatum : APIModel, Codable {
    var id: Int?
    var name: String?
    var odds: BetterOdds?
}

// MARK: - Odds
struct BetterOdds : APIModel, Codable {
    var data: [BetterOddsDatum]?
}

class BetterOddsDatum: APIModel , Codable {

    var label: String?
     //var extra: NSNull?
     //var probability, dp3: String?
     var american: Int?
     //var factional, handicap: NSNull?
     var total: String?
     var winning: Bool?
     var stop: Bool?
     var bookmakerEventID: Int?
    //private var odd: Double
    public var value: String?
    init() {

    }
}
5
  • 1
    Pleas show us the the code / data model Commented Feb 20, 2020 at 11:42
  • it is not alphabetically, datetime or anytype i could access. so you are saying there is no way to sort the array and still you want to sort it. Commented Feb 20, 2020 at 11:47
  • So you want to have a custom sorting order? Commented Feb 20, 2020 at 12:09
  • The JSON is invalid. Also, the models you gave doesn't parse the JSON. Commented Feb 20, 2020 at 12:25
  • I have delete unnecessary parameters in json. Commented Feb 20, 2020 at 12:30

3 Answers 3

2

If I understand your question correctly you want to be able sort the data based on betting type but the value of betting types are not sortable if used as a String variable. The solution would be to converting them into enum types with raw values and then sorting the array based on those raw values. Here is an example:

// Create a BetType for your datas
enum BetType: Int {
  case overUnder = 0
  case threeWayResult = 1 // 3WayResult
  ...
}

// Update your BetterOdd
struct BetterOdd : APIModel, Codable {
    var id: Int?
    var name: String?
    var betType: BetType = .overUnder // or put your default value here
    var suspended: Bool?
    var bookmaker: BetterBookmaker?
   }

// Loop your BetterMatch property's odds value after fetching datas.
for i in 0..<betterMatch.odds {
   if betterMatch.odds[i].name == "over/under" {
      betterMatch.odds[i].betType = .overUnder
   }
   ... // Do the same for other types as well in else if blocks 
}

Another alternative would be to add a function for getting the type in BetterOdd

struct BetterOdd ... {
  ... // Your properties

  func getBetType() -> BetType {
    if name == "over/under" {
       return .overUnder
    } else if name == "3WayResult" {
       return .threeWayResult
    }
    ... // Other cases
  }
}

Finnaly for sorting you can do:

let result = betterMatch.odds.sorted({ $0.betType.rawValue > $1.betType.rawValue })
// or if you used the function solution
let result = betterMatch.odds.sorted({ $0.getBetType().rawValue > $1.getBetType().rawValue })

Since you are using a Codable approach you might need to loop the array and set the betType values based on name values.

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

4 Comments

You understand correctly but there is a issue. case can not start with number so it says in editor "'W' is not a valid digit in integer literal". How to match if it is 3 way result or Correct Score etc..
Oh that's my bad case 3WayResult is not valid try to use it as case threeWayResult. Enum cases can't start with numbers. I've updated my answer accordingly.
then how to know if threeWayResult is 3 Way Result in my array?
I've updated my answer to fit this need. Like I said since you are using Codable the code can't parse your JSON data into an enum thus you need to set the betType value manually.
1

i changed model

struct BetterOdd : APIModel, Codable {
    var id: Int?
    var name: String?
    var suspended: Bool?
    var bookmaker: BetterBookmaker?
    //var betType: BetType = .threeWayResult

    enum BetType:Int, APIModel, Codable {
        case threeWayResult = 7
        case overUnder = 6
        case doubleChance = 5
        case bothTeamsToScore = 4
        case threeWayResultFirstHalf = 3
        case threeWayResultSecondHalf = 2
        case correctScore = 1
        case hTfTdouble = 0
    }
//
    func getBetType() -> BetType {
        if name == "3Way Result" {
            return .threeWayResult
        } else if name == "Over/Under" {
            return .overUnder
        } else if name == "Double Chance"  {
            return .doubleChance
        } else if name == "Both Teams To Score"  {
            return .bothTeamsToScore
        } else if  name == "3Way Result 1st Half" {
            return .threeWayResultFirstHalf
        } else if name == "3Way Result 2nd Half"{
            return .threeWayResultSecondHalf
        } else if name == "Correct Score"{
            return .correctScore
        } else if name == "HF/FT Double" {
            return .hTfTdouble
        } else {
            return .correctScore
        }
    }
}

and then :

let matchOddsArray  = match.odds!
let result = matchOddsArray.sorted(by: { $0.betType.rawValue > $1.betType.rawValue})
let bet = result[indexPath.row]

works perfect.

Comments

0

First of all, mark result in BetterMatchResults and odds in BetterMatch as var, i.e.

struct BetterMatchResults: Codable {
    let success: Bool
    var result: [BetterMatch] //here....
}

struct BetterMatch: Codable {
    var odds: [BetterOdd] //here....
    //rest of the parameters...
}

Next, while parsing your JSON data, use map(_:) and sorted(by:) to modify the result and odds in the betterMatchResults, i.e.

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    var betterMatchResults = try JSONDecoder().decode(BetterMatchResults.self, from: data)

    betterMatchResults.result = betterMatchResults.result.map {(betterMatch) in
        var match = betterMatch
        match.odds =  match.odds.sorted(by: { $0.name < $1.name })
        return match
    }

    //Test the response...
    print(betterMatchResults.result.map({ $0.odds.map({ $0.name }) })) //[["3Way Result", "Correct Score", "Over/Under"]]

} catch {
    print(error)
}

1 Comment

Ayazman's answer solved the problem. Since i use callback for fetching data i didn't want to change network class. Thanks anyway.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.