Это очень хороший пример того, почему вам настоятельно не рекомендуется использовать NSArray
и NSDictionary
в Swift.
Оба типа коллекции не предоставляют информацию о типе, поэтому все рассматривается как Any
. Большая часть общего универсального API стандартной библиотеки Swift не может использоваться с Any
, поэтому вы не сможете воспользоваться мощными универсальными функциями, если не добавите много уродливых приведений типов.
Если все значения String
, объявите ваш массив как
var json = [[String:String]]()
Затем вы можете отсортировать массив с помощью
let sortedArray = json.sorted { $0["Score"]! < $1["Score"]! }
Наиболее рекомендуемое решение - декодировать JSON непосредственно в пользовательскую структуру
struct Player : Decodable {
let name : String
let score : String
private enum CodingKeys : String, CodingKey { case name = "Name", score = "Score" }
}
Затем вы избавляетесь от всех типов приведения и можете сортировать по имени свойства
var players = [Player]()
let jsonString = """
[{"Name" : "Alen", "Score" : "500"},
{"Name" : "John", "Score" : "0"},
{"Name" : "Mark", "Score" : "2000"},
{"Name" : "Steve", "Score" : "300"},
{"Name" : "Ricky", "Score" : "900"}]
"""
let data = Data(jsonString.utf8)
do {
players = try JSONDecoder().decode([Player].self, from: data)
let sortedPlayers = players.sorted{ $0.score.compare($1.score, options: .numeric) == .orderedAscending }
print(sortedPlayers)
} catch { print(error) }
Edit:
Для загрузки JSON используйте асинхронный способ (URLSession
)
Никогда не загружайте данные с удаленного URL с синхронным Data(contentsOf
.
var players = [Player]()
let jsonUrl = URL(string: "url.json")!
let task = URLSession.shared.dataTask(with : url) { [unowned self] (data, _, error) in
if let error = error { print(error); return }
do {
players = try JSONDecoder().decode([Player].self, from: data!).sorted{ $0.score < $1.score }
DispatchQueue.main.async { // reload the table view if necessary
self.tableView.reloadData()
}
} catch { print(error) }
}
task.resume()