Mohammad Reza Koohkan
Mohammad Reza Koohkan

Reputation: 1734

How to sort JSON in swift based on persian characters

i am new to swift , i going to sort a json file in bundle not by code , is there anyway to sort the file using by code or not , i want to sort it from "citname":"لومار"

the json file is :

{


    "data":[
        {
            "_id":1,
            "citproidint":4,
            "citname":"لومار"
        },
        {
            "_id":2,
            "citproidint":4,
            "citname":"ايوان"
        },
        {
            "_id":3,
            "citproidint":12,
            "citname":"آبعلی"
        },
        {
            "_id":4,
            "citproidint":25,
            "citname":"نيشابور"
        },
        {
            "_id":5,
            "citproidint":27,
            "citname":"سقز"
        }, 

        ]

}

... // 827 id is in this json file and for every block in this json file i parse like this , and everything is fine but i want to use it sorted in my pickerview then i need to save sorted modals

guard let path = Bundle.main.path(forResource: "citybig", ofType: "json") else { return }
// city Text  file:// ...
let url = URL(fileURLWithPath: path)
do {
    // data explained in bytes
    let data = try Data(contentsOf: url)
    // we get the json file text
    let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
    // put json in nsdictinary so we can access each index and person sooo ... id and more

    for (key,value) in json as! NSDictionary {
        if (key as! String) == "data" {
            let value2 = value.s
            for each in value as! [[String: Any]] {
        let singleCityModal = cityModal()
    for (key,value) in each {
        switch key {
        case "_id" :
            singleCityModal.id = value as? Int
        case "citproidint" :
            singleCityModal.citproidint = value as? Int
        case "citname" :
            singleCityModal.citname = value as? String
        default:
            break
            }
        } 
   cityFirstModal.append(singleCityModal)
    }

    cityFinalModal.append(contentsOf: cityFirstModal)

Upvotes: 1

Views: 138

Answers (1)

vadian
vadian

Reputation: 285059

Your way to parse the data is quite strange, in Swift 4 there is a more convenient way, the Decodable protocol.

You need two structs:

struct CityData : Decodable {
    private enum CodingKeys: String, CodingKey { case cities = "data"}

    let cities : [City]
}

struct City : Decodable {
    private enum CodingKeys: String, CodingKey { case id = "_id", citproidint, name = "citname"}

    let id, citproidint: Int
    let name : String
}

and the code to parse the JSON becomes a bit shorter (and more efficient)

let url = Bundle.main.url(forResource: "citybig", withExtension: "json")!
let data = try! Data(contentsOf: url)
let cityData = try! JSONDecoder().decode(CityData.self, from: data)

The exclamation marks are intended. As the (immutable) file is in the bundle the code must not crash. If it does you made a design mistake.

It's just one additional line to sort the cities by citproidint

let sortedCities = cityData.cities.sorted(by: {$0.citproidint < $1.citproidint})

I'm not familiar with Farsi but if you want to sort by name the selector localizedStandardCompare might do the job

let sortedCities = cityData.cities.sorted(by: {$0.name.localizedStandardCompare($1.name) == .orderedAscending })

Upvotes: 2

Related Questions