2017-10-04 89 views
1

这是我现在的模型类代码。如何在Swift中按名字排序数组?

final class ContactData 
{ 
    static let sharedInstance = ContactData() 

    private var contactList : [Contact] = 
      [Contact(name:"Mike Smith",email:"[email protected]"), 
      Contact(name:"John Doe",email:"[email protected]"), 
      Contact(name:"Jane Doe",email:"[email protected]")] 


    private init() 
    { 
     // SORTING HERE 
    } 

    var index = 0 

    func newContact(new:Contact) 
    { 
     contactList.append(new) 
     //sort 
    } 

    func updateContact(updated:Contact) 
    { 
     contactList[index]=updated 
     //sort 
    } 

    func previousContact() -> Contact 
    { 
     index-=1 
     if index < 0 
     { 
      index = contactList.count-1 
     } 
     return contactList[index] 
    } 

    func nextContact() -> Contact 
    { 
     index+=1 
     if index == contactList.count 
     { 
      index = 0 
     } 
     return contactList[index] 
    } 

    func firstContact() -> Contact 
    { 
     return contactList[0] 
    } 

    func currentContact() -> Contact 
    { 
     return contactList[index] 
    } 
} 

一切运行正常,但我已经尝试使用字母排序的Contact在数组:

var sortedContacts = contactList.sorted{ 
      $0.localizedCaseinsensitiveCompare($1)==ComparisonResult.orderedAscending} 
     } 

但我得到一个错误:

Value of type ' Contact ' has no member ' localizedCaseinsensitiveCompare '

通过提问看这里我只能找到这种单一的方式来按字母顺序排列数组。

我正在斯威夫特3和Xcode的8.3

回答

1

你应该让你的类联系符合可比协议:

class Contact: Comparable, CustomStringConvertible { 
    let name: String 
    let email: String 
    init(name: String, email: String) { 
     self.name = name 
     self.email = email 
    } 
    var description: String { 
     return name + " - " + email 
    } 
    // provide your custom comparison 
    static func <(lhs: Contact, rhs: Contact) -> Bool { 
     return lhs.name.localizedCaseInsensitiveCompare(rhs.name) == .orderedAscending || 
       lhs.email.localizedCaseInsensitiveCompare(rhs.email) == .orderedAscending 
    } 
    // you will need also to make it conform to Equatable 
    static func ==(lhs: Contact, rhs: Contact) -> Bool { 
     return lhs.name == rhs.name && lhs.email == rhs.email 
    } 
} 

游乐场测试

let c1 = Contact(name:"Mike Smith",email:"[email protected]") 
let c2 = Contact(name:"John Doe",email:"[email protected]") 
let c3 = Contact(name:"John Doe",email:"[email protected]") 
let c4 = Contact(name:"Jane Doe",email:"[email protected]") 
let c5 = Contact(name:"Jane Doe",email:"[email protected]") 

let people = [c1, c2, c3, c4, c5] 
print(people) // "[Mike Smith - [email protected], John Doe - [email protected], John Doe - [email protected], Jane Doe - [email protected], Jane Doe - [email protected]]\n" 
print(people.sorted()) // "[Jane Doe - [email protected], Jane Doe - [email protected], John Doe - [email protected], John Doe - [email protected], Mike Smith - [email protected]]\n" 
+0

这个解决方案需要考虑的一些事情。一切只与'name'有关。这假定你总是想按名称比较并忽略电子邮件。它将具有相同名称但不同电子邮件的两个不同联系人对等。这可能会导致很多微妙的错误。这可能是最好的,如果电子邮件比较的名称是平等的。 – rmaddy

+0

我的评论是给OP提供他的自定义排序 –

+0

或比较说明 –

0

你无法不区分大小写比较Contact自定义类的情况。你应该比较name性质其中:

var sortedContacts = contactList.sorted { $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending} } 
+1

或接通符合可比较的协议 –

+0

@LeoDabus是的,如果您计划的话,这是一个更好的方法o在你的代码中使用很多排序。 – the4kman

+0

@ the4kman通过在我的操场上做到这一点,它现在抛出一个错误,其中我的功能基本上不是nonsexist。 – Nonstoplive