2014-09-10 3 views
22

В Objective-C я могу сортировать NSArray используя эту инструкцию:Сортировать NSArray с sortedArrayUsingComparator

NSArray *sortedArray = [persons sortedArrayUsingComparator:^NSComparisonResult(Person *p1, Person *p2) { 
    return [p1.name compare:p2.name]; 
}]; 

Я не в состоянии воспроизвести то же самое заявление с Swift. Все, что я нашел, было Array.

ответ

35

Вы можете использовать либо Swift's built in sort functions или, так как массив Swift соединен с мостом до NSArray, вы можете позвонить по телефону sortedArrayUsingComparator прямо из swift.

Использование sorted функции Свифта:

var sortedArray = sorted(persons) { 
    (obj1, obj2) in 

    // The downcast to Person is only needed if persons is an NSArray or a Swift Array of AnyObjects 
    let p1 = obj1 as Person 
    let p2 = obj2 as Person 
    return p1.name < p2.name 
} 

Или, используя NSArray «s sortedArrayUsingComparator:

var sortedArray = persons.sortedArrayUsingComparator { 
    (obj1, obj2) -> NSComparisonResult in 

    let p1 = obj1 as Person 
    let p2 = obj2 as Person 
    let result = p1.name.compare(p2.name) 
    return result 
} 
+0

'NSComparisonResult' теперь' ComparisonResult'. – ThomasW

9

Так что попробуйте просто написать то же самое с Swift:

var sortedArray:NSArray = 
persons.sortedArrayUsingComparator(){(p1:AnyObject!, p2:AnyObject!) -> NSComparisonResult in 

    if (p1 as Person).name > (p2 as Person).name { 
     return NSComparisonResult.OrderedDescending 
    } 
    if (p1 as Person).name < (p2 as Person).name { 
     return NSComparisonResult.OrderedAscending 
    } 
    return NSComparisonResult.OrderedAscending 
} 

Test (площадка):

class Person{ 
    var name:String? 
} 

var p1:Person = Person() 
p1.name = "a"  

var p3:Person = Person() 
p3.name = "c" 

var p2:Person = Person() 
p2.name = "b" 

var persons:NSArray = [p1,p3,p2] 

var sortedArray:NSArray = persons.sortedArrayUsingComparator(){ 

    (p1:AnyObject!, p2:AnyObject!) -> NSComparisonResult in 

    if (p1 as Person).name > (p2 as Person).name { 
     return NSComparisonResult.OrderedDescending 
    } 
    if (p1 as Person).name < (p2 as Person).name { 
     return NSComparisonResult.OrderedAscending 
    } 
    return NSComparisonResult.OrderedAscending 
    } 

for item:AnyObject in sortedArray{ 
    println((item as Person).name) 
} 

Выход:

Optional("a") 
Optional("b") 
Optional("c") 
13

Там нет необходимости, чтобы избежать Swift Array.

Он соединен в обоих направлениях с помощью NSArray, поэтому для более безопасного ввода кода лучше всего выполнять свою работу с массивами Swift и мостом только тогда, когда это необходимо для взаимодействия с API-интерфейсами ObjC. (И в большинстве импортируемых API-интерфейсах, Swift автоматически преобразует NSArray в [AnyObject], так что вам даже не нужно преодолеть очень часто.)

Предполагая persons массива является [AnyObject] вы получили от других API, вы можете сократить на количество отливки типа по отношению к другим ответам литья массива первым:

let sortedPersons = sorted(persons as [Person]) { $0.name < $1.name } 
// sortedPersons has inferred type [Person] 

Кроме того, так как вы используете компаратор блок только для сортировки определенного свойства вашего Person класса, вы могли бы сделать лучше использовать сорт дескрипторы:

let sortedPersons = (persons as NSArray).sortedArrayUsingDescriptors([ 
    NSSortDescriptor(key: "name", ascending: true) 
]) 

(The persons as NSArray часть не может быть необходима, если persons происходил из ObjC API.)

В зависимости от того, как реализован Person класса, сортировка с дескрипторами может производить более эффективный вид на внутреннем интерфейсе. Например, если это управляемый объект с базовыми данными, сортировка с дескрипторами может привести к выполнению SQL-запроса, который выполняется быстро в базе данных и использует небольшую память, в то время как сортировка с закрытием компаратора требует создания экземпляра каждого объекта из базы данных только для оценки закрытия по каждому ,

+0

Большое спасибо @rickster. Это было полезно для меня. – Raja

+0

Второй работал для меня. – NSPratik

0

В Swift вы можете использовать новый подход. Попробуйте использовать отсортированный метод вместо sortedArrayUsingComparator следующим образом ...

var sortedArray = results.sorted { 
    (obj1, obj2) -> Bool in 
    return obj1.count! > obj2.count! 
} 
0

в случае, если у вас есть собственный объект и хотите отсортировать по дате

let sortedArray = self.posts.sorted { 
      (obj1, obj2) -> Bool in 
      return (obj1 as! PostModel).orderCancellionDate.compare((obj2 as! PostModel).orderCancellionDate) == .orderedDescending 
     }