Carpetfizz
Carpetfizz

Reputation: 9169

Unable to sort a Swift array

I'm trying to sort my contacts array by severity

    var contacts: [Contact]?   

    if let customer = CoreDataAccess.sharedInstance.getSavedCustomer() {
       //Cast from NSSet to [Contact]        
       self.contacts = customer.contacts.allObjects as? [Contact]
       self.contacts!.sort({$0.severity < $1.severity}) //error
    }

The compiler errors out at the marked line with the following message:

Cannot invoke 'sort' with an argument list of type '((_, _) -> _)'

I'm not sure what I'm doing wrong because this exact same thing worked in another file. If it helps to explain, the above code crashes when running on the WatchKit interface, but not when used in iOS.

EDIT: severity is an NSNumber

Upvotes: 4

Views: 935

Answers (3)

vadian
vadian

Reputation: 285250

Try to cast the first argument explicit to NSNumber and use the compare: method (I tested it in a Playground)

var contacts: [Contact]?
if let customer = CoreDataAccess.sharedInstance.getSavedCustomer() {
    //Cast from NSSet to [Contact]
    self.contacts = customer.contacts.allObjects as? [Contact]
    self.contacts!.sort { ($0.severity as NSNumber).compare($1.severity) == .orderedAscending }
}

It's even more efficient to declare the relationship as native Swift set Set<Contact> and the attribute as Int, this avoids to call allObjects and the type casts. And declare contacts as non-optional empty array.

var contacts = [Contact]()
if let customer = CoreDataAccess.sharedInstance.getSavedCustomer() {
    self.contacts = customer.contacts.sorted { $0.severity < $1.severity }
}

Upvotes: 2

Yu-Lin Wang
Yu-Lin Wang

Reputation: 131

I think the problem is the property of Contact "severity" !

The type of "severity" is your custom type, and it's not implement compare operator like "<"

Since severity is NSNumber We can do this

func <(lhs: NSNumber, rhs: NSNumber) -> Bool {
    return lhs.compare(rhs) == NSComparisonResult.OrderedAscending
}
func >(lhs: NSNumber, rhs: NSNumber) -> Bool {
    return lhs.compare(rhs) == NSComparisonResult.OrderedDescending
}
func ==(lhs: NSNumber, rhs: NSNumber) -> Bool {
    return lhs.compare(rhs) == NSComparisonResult.OrderedSame
}

then the code will works fine.

Upvotes: 1

avismara
avismara

Reputation: 5149

Try this:

var contacts: [Contact]?   
if let customer = CoreDataAccess.sharedInstance.getSavedCustomer() {
   //Cast from NSSet to [Contact]        
   self.contacts = customer.contacts.allObjects as? [Contact]
   self.contacts!.sort {
       $0.severity < $1.severity
   }
}

Upvotes: 0

Related Questions