Как отсортировать JSON, поступающий от Alamofire, и вернуть окончательный объект JSON (swiftyJSON)

У меня возникли проблемы с кратким извлечением данных из API, добавлением текущего местоположения пользователя в объект и последующей сортировкой данных на основе рассчитанного расстояния.

Вопросы stackoverflow не совсем отвечают на проблему, с которой я столкнулся. См. здесь: Как сортировать сообщения, прочитанные из JSON. файл сервера в Swift.

В настоящее время я загружаю данные API из Alamofire и отображаю эти данные с помощью UITableViewController.

    override func viewDidLoad() {
    super.viewDidLoad()
    titleLabel.title = q.capitalizedString
    Alamofire.request(.GET, "http://www.thesite.com/api/v1/things", parameters: ["q" : q])
        .responseJSON { response in
            let JSONObject = JSON(response.result.value!)
            self.results = JSONObject["things"]
            for (key, _) in self.results {
                let intKey: Int = Int(key)!
                var thisItem: JSON = self.results[intKey]
                let geoLat = thisItem["place"][0]["location"]["geo"][1].double ?? 37.763299
                let geoLong = thisItem["place"][0]["location"]["geo"][0].double ?? -122.419356
                let destination = CLLocation(latitude: geoLat, longitude: geoLong)
                let setLocation = CLLocation(latitude: self.currentLocation.latitude, longitude: self.currentLocation.longitude)
                let distanceBetween: CLLocationDistance = destination.distanceFromLocation(setLocation)
                thisItem["distance"].double =  distanceBetween
                self.results[intKey] = thisItem
            }
            self.tableView.reloadData()
    }
}

Я получаю данные из API и успешно добавляю расстояние между местоположением пользователя и местом назначения.

Однако теперь мне нужно отсортировать объект JSON (SwiftyJSON) от наименьшего до наибольшего расстояния. Вот где я застрял.

структура данных в момент перезагрузки tableView (как объекта JSON) по существу:

results = [
{"title": "Chai", "distance": "1245.678575"},
{"title": "Espresso", "distance": "765845.678575"},
{"title": "Drip Coffee", "distance": "23445.678575"}
...
]

Как бы я мог: 1) преобразовать объект в NSArray и отсортировать; или 2) просто отсортировать объект? Когда лучше всего добавлять и сортировать расстояние - следует ли мне делать это перед преобразованием в объект JSON.

Любая помощь приветствуется! Спасибо!


person Ryan Walton    schedule 26.10.2015    source источник


Ответы (3)


Если results является объектом SwiftyJSON, вы можете извлечь его массив с помощью .arrayValue.

let resultsArray = results.arrayValue

Затем, когда у вас есть нормальный массив словарей, вы можете отсортировать массив с помощью sort следующим образом:

let sortedResults = resultsArray.sort { $0["distance"].doubleValue < $1["distance"].doubleValue }

Я взял ваш фрагмент JSON:

введите описание изображения здесь

И проверил мой ответ на игровой площадке с помощью SwiftyJSON:

введите описание изображения здесь


Если вы хотите, вы также можете отсортировать объект SwiftyJSON напрямую:

let sortedResults = results.sort { $0.0.1["distance"].doubleValue < $0.1.1["distance"].doubleValue }.map { $0.1 }

Но я нахожу его менее читаемым как исходный код.

person Eric Aya    schedule 26.10.2015
comment
Спасибо! Это сработало отлично. Благодарим вас за то, что вы нашли решение, которое сработало в данных обстоятельствах. - person Ryan Walton; 27.10.2015
comment
Я получил Argument passed to call that takes no arguments ошибку при сортировке {}. - person Jin Wang; 27.03.2017
comment
Этот ответ был для Swift 2. В Swift 3 замените sort на sorted (и замените sortInPlace на sort). В любом случае вы должны искать контент Swift 3. - person Eric Aya; 27.03.2017
comment
@EricAya, как сортировать по возрастанию в приведенном выше примере? и не могли бы вы объяснить использование $0.0.1 и $0.1.1, как работает приведенный выше код - person Varun Naharia; 10.05.2017

Свифт 3 и Свифт 4

let sortedResults = finalJsonArray.sorted { $0["count"].doubleValue < $1["count"].doubleValue }
person Ahmed Safadi    schedule 23.10.2017

Swift 3 + Swift 4 Самое короткое решение, которое я нашел, приведено ниже:

< сортирует по возрастанию,
> сортирует по убыванию

Это особенно эффективно для сортировки в формате (String,JSON) (когда вы работаете со SwiftyJSON).

let sortedResults = json.sorted(by: < )
person Trevor    schedule 26.01.2018