0

I am getting a response in this format

[
    "1234": {
        "startDate": "1536278400",
        "endDate": "1536796800",
        "playerRank": 1,
        "performance": 100,
        "isProfit": false,
        "members": 1
    },
    "adityaKumar": {
        "startDate": "1536364800",
        "endDate": "1540080000",
        "playerRank": 1,
        "performance": 100,
        "isProfit": false,
        "members": 6
    },
    "madhu60": {
        "startDate": "1539388800",
        "endDate": "1539475200",
        "playerRank": 1,
        "performance": 100,
        "isProfit": false,
        "members": 2
    }
]

This response is of type [string:Any]. I have to sort the data using the playerRank property. I want the output to be of type [string:Any].

How is this possible in Swift?

11
  • 2
    You'd probably want to use json parser. Then you can filter. Commented Oct 24, 2018 at 12:11
  • 2
    @Aditya, [String: Any] is a dictionary which is an unordered set of data. You will not get desired data with this format, rather you can have an array of this data with user-name as well in the data-set(dictionary). Then you can apply sorting as array is an ordered set of data. Commented Oct 24, 2018 at 12:15
  • One more question that playerRank for all the user is same, how can you sort then? Commented Oct 24, 2018 at 12:17
  • @AnkitJayaswal I didn’t post full response. So, there is no solution for this Commented Oct 24, 2018 at 12:21
  • @Aditya, if you can change in server-response, then you can convert it at your end, and map the dictionary in array with user-name then you can simply sort the array. Commented Oct 24, 2018 at 12:26

3 Answers 3

0

A dictionary is unsorted

From swift documentation

A dictionary stores associations between keys of the same type and values of the same type in an collection with no defined ordering.

However, you can use the .sorted method on your dictionary which will give you an array of dictionaries (arrays are sortable).

let sorted = dictionary.sorted(by: { ($0.value["playerRank"]) < ($1.value["playerRank"]) })

From your original example sorted might look like this

[
    (
      "key": "madhu60",
      "value": {
         "startDate": "1539388800",
         "endDate": "1539475200",
         "playerRank": 1,
         "performance": 100,
         "isProfit": false,
         "members": 2
      }
   )
   ....
]
Sign up to request clarification or add additional context in comments.

6 Comments

hai @Josh can u please explain me briefly
@Aditya what is that you do not understand?
after getting this response it is in the format of [key:string, value:Any]. then how to convert this response into [string: any]
I think the issue is, you do not want a type [string: any] since this is not orderable. You can leave it in this format and use it however you would like for your UI.
Hai @Josh can u please help how to apply that data to tableview because it is in different format. I am trying but it is showing error
|
0

Once you parse that JSON, you'll get a dictionary of type [String: [String:Any]], i.e.

let data = [
    "1234": [
        "startDate": "1536278400",
        "endDate": "1536796800",
        "playerRank": 1,
        "performance": 100,
        "isProfit": false,
        "members": 1
    ],
    "adityaKumar": [
        "startDate": "1536364800",
        "endDate": "1540080000",
        "playerRank": 1,
        "performance": 100,
        "isProfit": false,
        "members": 6
    ],
    "madhu60": [
        "startDate": "1539388800",
        "endDate": "1539475200",
        "playerRank": 1,
        "performance": 100,
        "isProfit": false,
        "members": 2
    ]
]

You can sort this dictionary simply using sorted method, i.e.

let sortedData = data.sorted { 
    if let rank1 = $0.value["playerRank"] as? Int, let rank2 = $1.value["playerRank"] as? Int
    {
        return rank1 < rank2
    }
    return false
}

And you are good to go.

4 Comments

hai @PGDev I am getting response in this format [(key: String, value: [String : Any])] but how to this data convert to [string:Any] (OR) I have to assign the data to table view. [ (key: "madhu60", value: [ "members": 2, "endDate": 1539475200, "playerRank": 1, "isProfit": 0, "startDate": 1539388800, "performance": 100 ])]
I don't understand what you are asking. Please elaborate.
I am getting response. in the type of [(key:string, value:Any)] now I have to assign this response to Tableview. Can u tell me how to assign this format of response. [ ( "key": "madhu60", "value": { "startDate": "1539388800", "endDate": "1539475200", "playerRank": 1, "performance": 100, "isProfit": false, "members": 2 } ) .... ]
What do you mean by you have assigned it to tableView?
0

I show you a complete answer here.

First convert the response text to a qualified JSON Data.

Second build a customized structure to decode JSON Data to.

Third sort the structure

Last to print back to original response text (You may use a string to have the print result.)

First:

            let json = """
    [
        "1234": {
            "startDate": "1536278400",
            "endDate": "1536796800",
            "playerRank": 4,
            "performance": 100,
            "isProfit": false,
            "members": 1
        },
        "adityaKumar": {
            "startDate": "1536364800",
            "endDate": "1540080000",
            "playerRank": 2,
            "performance": 100,
            "isProfit": false,
            "members": 6
        },
        "madhu60": {
            "startDate": "1539388800",
            "endDate": "1539475200",
            "playerRank": 1,
            "performance": 100,
            "isProfit": false,
            "members": 2
        }
    ]
    """.replacingOccurrences(of: "[", with: "{").replacingOccurrences(of: "]", with: "}").data(using: .utf8)

second:

    struct Response  {
     struct ResponseData  {
        let name : String
         let startDate : String
         let endDate : String
         let performance : Int
         let playerRank : Int
         let isProfit : Bool
         let members : Int
        }
        var responseData: [ResponseData]
        init (responseData: [ResponseData] = []){
            self.responseData = responseData
        }
    }

     extension Response: Decodable {

        struct DataKey: CodingKey {
                    var stringValue: String
                    init?(stringValue: String) {
                        self.stringValue = stringValue
                    }
                    var intValue: Int? { return nil }
                    init?(intValue: Int) { return nil}

                    static let startDate = DataKey(stringValue: "startDate")!
                    static let endDate = DataKey(stringValue: "endDate")!
                    static let performance = DataKey(stringValue: "performance")!
                    static let playerRank = DataKey(stringValue: "playerRank")!
                    static let isProfit = DataKey(stringValue: "isProfit")!
                    static let members = DataKey(stringValue: "members")!
                }

        public init(from decoder: Decoder) throws {
            var responseData = [ResponseData]()
            let container = try decoder.container(keyedBy: DataKey.self)
            for key in container.allKeys {
                let dataContainer = try container.nestedContainer(keyedBy: DataKey.self, forKey: key)

                let startDate = try dataContainer.decode(String.self, forKey: .startDate)
                 let endDate = try dataContainer.decode(String.self, forKey: .endDate)
                 let performance = try dataContainer.decode(Int.self, forKey: .performance)
                 let playerRank = try dataContainer.decode(Int.self, forKey: .playerRank)
                 let isProfit = try dataContainer.decode(Bool.self, forKey: .isProfit)
                 let members = try dataContainer.decode(Int.self, forKey: .members)
                let each = ResponseData.init(name: key.stringValue, startDate: startDate, endDate: endDate, performance: performance, playerRank: playerRank, isProfit: isProfit, members: members)
                responseData.append(each)
            }
            self.init(responseData: responseData)
        }
    }

    let decoder = JSONDecoder()
    var decodedStore = try decoder.decode(Response.self, from: json!)

third:

      decodedStore.responseData.sort{$0.playerRank < $1.playerRank }

last:

     print ("[")
    for each in decodedStore.responseData {
        print ("""
               \(each.name): {
                        "startDate": \(each.startDate),
                        "endDate": \(each.endDate),
                        "playerRank": \(each.playerRank),
                        "performance": \(each.performance),
                        "isProfit": \(each.isProfit),
                        "members": \(each.members)
                        }
            """)
    }
    print ("]\n")

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.