2014-09-10 122 views
22

Objective-C我可以用這個語句排序的NSArray排序的NSArray與sortedArrayUsingComparator

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

我無法重現相同的語句斯威夫特。我發現的全部是使用Array

回答

35

您可以使用Swift's built in sort functions或者,由於Swift數組橋接到NSArray,因此您可以直接從swift中調用sortedArrayUsingComparator

使用雨燕的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 
} 

或者,使用NSArraysortedArrayUsingComparator

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 2018-02-19 05:27:11

9

所以儘量只寫相同與斯威夫特:

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 
} 

測試(遊樂場):

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

有沒有必要,以避免斯威夫特Array

它與NSArray這兩個方向橋接,因此對於更多類型安全的代碼,最好使用Swift數組完成工作,並且只在需要與ObjC API進行互操作時進行橋接。 (在大部分進口的API,雨燕自動轉換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) 
]) 

(該persons as NSArray部分可能不是必要的,如果persons從ObjC API來了。)

根據Person類是如何實現的,與描述排序可以產生在後端更有效的排序。例如,如果它是一個核心數據管理對象,則使用描述符排序可能會產生一個SQL查詢,該查詢在數據庫中執行得很快,並且使用很少的內存,而使用比較器閉包進行排序需要實例化數據庫中的每個對象,以評估每個對象。

+0

非常感謝你@rickster。這對我很有用。 – Raja 2017-09-24 04:46:48

+0

第二個爲我工作..upvoted! – NSPratik 2017-12-15 10:00:21

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 
     }