2

I am using SwiftyJSON to parse the JSON from web, and then displaying those values in a tableView. I want to add a functionality to sort the data alphabetically ascending or descending according to the user names. I am new to Swift and having trouble sorting this. I would appreciate any help!

override func viewDidLoad(){
super.viewDidLoad()
getContactListJSON()
}

func getContactListJSON(){
let urlString = "http://jsonplaceholder.typicode.com/users"
let urlEncodedString = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let url = NSURL( string: urlEncodedString!)
var task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, innerError) in
self.json = JSON(data: data)
self.contactsArray = json.arrayValue

dispatch_async(dispatch_get_main_queue(), {

}
 task.resume()
}

This is how I am populating my tableView.

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? UITableViewCell

    if cell == nil {
        cell = UITableViewCell(style: UITableViewCellStyle.Value2, reuseIdentifier: "Cell")
    }

    cell!.textLabel?.text = self.contactsArray[indexPath.row]["name"].stringValue
    cell!.detailTextLabel?.text = self.contactsArray[indexPath.row]["email"].stringValue
   return cell!

}

2 Answers 2

3

You can sort a Swift Array by using array.sort

self.contactsArray.sort { $0 < $1 }

You can refer this for details.

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

10 Comments

Because $0 < $1 is intuitive.
LOL! @zaph yeah, took me a while to get my head around closure syntax.
@zaph I'm not a fan of the $0 $1 syntax either. With Swift closures you can always use a more verbose, but clearer form self.contactsArray.sort { first, second in first < second }
@carl_h first and second is just as imprecise as $0 and $1. It's just more typing. Either way does not express the data type. It could be anything that's comparable. Whereas if you use something like firstName and secondName it's pretty clear you're dealing with String. Not to say that any way is wrong... I personally don't mind the $0 < $1 syntax here. It probably won't sort correctly though. I'm assuming @swifty would want a case-insensitive sort.
@BenKane Fair enough, firstName and secondName then for clarity. It sounds like you're really expressing a dislike of type inferencing in general, whereas I was expressing a dislike of the shorthand argument names that Swift provides. Besides, if you want to be completely clear you could always spell it out in full { (firstName: String, secondName: String) -> Bool in return firstName < secondName }
|
0

After playing around a bit I found a more swift-friendly answer. I will leave the Objective-C style below as reference in case it's interesting. Of note – in this first example, the array being sorted must be mutable (var not let) for sort() to work. In the second example with Obj-C sort descriptors a new array is created and the original isn't mutated - similar to sorted()

    let contact1: [String: String] = ["name" : "Dare", "email" : "[email protected]"]
    let contact2: [String: String] = ["name" : "Jack", "email" : "[email protected]"]
    let contact3: [String: String] = ["name" : "Adam", "email" : "[email protected]"]

    var contacts = [contact1, contact2, contact3]

    contacts.sort({$0["name"] <  $1["name"]})

    println(contacts)

This is corrupted a bit by Objective-C but seems to work. The major benefit of this method over the other is that this is case-insensitive. Although I am sure there is a better way to do the same thing with newer syntax.

    let contact1: [String: String] = ["name" : "Dare", "email" : "[email protected]"]
    let contact2: [String: String] = ["name" : "Jack", "email" : "[email protected]"]
    let contact3: [String: String] = ["name" : "Adam", "email" : "[email protected]"]

    let contacts: Array = [contact1, contact2, contact3]

    let nameDiscriptor = NSSortDescriptor(key: "name", ascending: true, selector: Selector("caseInsensitiveCompare:"))

    let sorted = (contacts as NSArray).sortedArrayUsingDescriptors([nameDiscriptor])

    println(sorted)

//These print the following

    [
        {
            email = "[email protected]";
            name = Adam;
        },
        {
            email = "[email protected]";
            name = Dare;
        },
        {
            email = "[email protected]";
            name = Jack;
        }
    ]

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.