3

I'm having trouble succinctly pulling data from an api, adding the users current location into the object and then sorting the data based on the calculated distance.

The stackoverflow questions don't quite answer the problem I'm facing. See here: How to sort posts read from JSON server file in Swift.

I'm currently loading api data from Alamofire and rendering that data with a 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()
    }
}

I get the data from the api and successfully add the distance between the user's location and the destination of the place.

However, now I need to sort the JSON object (SwiftyJSON) from lowest to highest distance. This is where I'm stuck.

the data structure at the point the tableView (as JSON object) is reloaded is essentially:

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

How would I be able to either: 1) convert the object to NSArray and sort; or 2) just sort the object? When would be the best place to do the distance add and sort - should I do it before converting to the JSON object.

Any help is appreciated! Thanks!

0

3 Answers 3

11

If results is a SwiftyJSON object, you can extract its array with .arrayValue.

let resultsArray = results.arrayValue

Then once you have a normal array of dictionaries, you can then sort the array with sort like this:

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

I took your JSON snippet:

enter image description here

And tested my answer in a Playground with SwiftyJSON:

enter image description here


If you wanted to, you could also sort the SwiftyJSON object directly:

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

But I find it less readable as source code.

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

4 Comments

Thanks! That worked perfectly. Appreciate you finding a solution that worked given the circumstances.
I got Argument passed to call that takes no arguments error on the sort {}.
This answer was for Swift 2. In Swift 3, replace "sort" with "sorted" (and replace "sortInPlace" with "sort"). Anyway you should look for Swift 3 content.
@EricAya how to sort in Ascending order in above example ? and can you please explain usage of $0.0.1 and $0.1.1 how above code is working
0

Swift 3 & Swift 4

let sortedResults = finalJsonArray.sorted { $0["count"].doubleValue < $1["count"].doubleValue }

Comments

0

Swift 3 + Swift 4 Shortest solution I've found is below:

< is sorting ascending,
> is sorting descending

It is especially very efficient for sorting (String,JSON) format (when you work with SwiftyJSON)

let sortedResults = json.sorted(by: < )

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.