2014-09-10 56 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 
     }