如何在Swift中对数组进行排序

46

我需要这段代码的Swift版本:

NSArray *sortedNames = [names sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

请访问 https://developer.apple.com/swift/ 了解基础知识(包括排序)。 var sortedStrings = sorted(stringArray) { $0.uppercaseString < $1.uppercaseString } - Danielson
8个回答

73
var names = [ "Alpha", "alpha", "bravo"]
var sortedNames = names.sorted { $0.localizedCaseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending }
更新:按照另一位SO用户的建议提供解释。
与ObjC不同,在Swift中,您有sorted()(和sort())方法,该方法使用您提供的闭包,该闭包返回一个布尔值,以指示是否应将一个元素放在另一个元素之前(true)还是之后(false)。 $0和$1是要比较的元素。我使用localizedCaseInsensitiveCompare来获得您要查找的结果。现在,localizedCaseInsensitiveCompare返回排序类型,因此我需要修改它以返回适当的bool值。
Swift 2更新: sortedsort已被sortsortInPlace替换。

1
请解释一下这段代码是如何工作的。这可以最大程度地减少抄袭和粘贴而没有清晰的理解。 - rayryeng
肯定没有“sorted”方法,应该是sort。我在Swift2.0上验证过了。 - LiangWang
@Jacky - 是的,它在Swift 2中发生了变化。 - MirekE
1
只有使用sort()而不是sorted()才能正常工作。我正在使用Xcode 7.3。无法确定结果是否符合原始代码的意图。 - Cue
@Tel - 原始代码是在 Swift 2.0 之前的版本。2015 年有一个更新,指出你需要在 Swift 2 中使用 sort 而不是 sorted - MirekE
显示剩余3条评论

22

在 Swift 中对数组进行排序

定义一个初始的名字数组:

var names = [ "gamma", "Alpha", "alpha", "bravo"]

方法1:

var sortedNames = sorted(names, {$0 < $1})
// sortedNames becomes "[Alpha, alpha, bravo, gamma]"

这可以进一步简化为:

var sortedNames = sorted(names, <)
// ["Alpha", "alpha", "bravo", "gamma"]
var reverseSorted = sorted(names, >)
// ["gamma", "bravo", "alpha", "Alpha"]

方法2:

names.sort(){$0 < $1}
// names become sorted as this --> "[Alpha, alpha, bravo, gamma]"

var names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]var sortedNames = names.sorted(by: {$0 < $1})print(sortedNames)var sortedNames2: () = names.sort(by: {$0 < $1}) print(sortedNames2)为什么sortedNames2返回一个空数组? 谢谢 - DrDev
谢谢。它帮了我很多。 - Alexander Khitev

17
如果您的数组不包含自定义对象(只是字符串或数字类型):
var sortedNames = sorted(names, <)
否则,如果您在内部创建一个包含自定义属性的自定义数据对象类:
customDataObjectArray.sort({ $0.customProperty < $1.customProperty })

7

在SWIFT中排序的最有效方法

在Swift语言中,使用运算符重载是对字符串进行排序的最有效方法。

// OPERATOR OVERLOADING
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
var sortedNames = sorted(names, <)
var reverseOrder = sorted(names, >)

在上述代码中,Swift重载了><运算符以对字符串进行排序。
我已在Playground中测试了该代码,并得出结论,当我们使用运算符重载时,最适合对字符串进行排序。
将下面的内容复制到Playground中。
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

var reversed = sorted (names,
    // This is a closure
    { (s1 : String, s2 : String) -> Bool in
        return s1 > s2
    }
)
println(reversed)

var reverseOrder = sorted(names, {s1, s2 in s1 > s2})

var reverseOrder2 = sorted(names, { $0 > $1} )

// OPERATOR OVERLOADING
var reverseOrder3 = sorted(names, >)

从Playground得出的结论:

enter image description here

从上面的图像可以看出,所有其他方法都需要枚举循环来排序5个字符串。而当我们使用运算符重载时,不需要枚举循环来排序字符串。
引用自Swift文档

4
如果您想将数组按升序排序,请使用以下语法:
var arrayName = sorted(arrayName, <)

sorted()是Swift中预定义的函数,其中使用<表示数组应按升序排序。如果您想按降序对数组进行排序,则只需用>替换<,如下所示:

var arrayName = sorted(arrayName, >)

1
在 Swift 2 中:arrayName = arrayName.sort(>) - josef

2
任何可以与Objective-C中的sortedArrayUsingSelector:方法一起使用的方法都可以在Swift sort(或sorted)中使用,只要数组中的元素类型是已知的。因此,在您的代码中:
var arr : [String] = // ...
// it is an array of String, so we can use localizedCaseInsensitiveCompare:
sort(&arr) {return $0.localizedCaseInsensitiveCompare($1) == .OrderedAscending}

同样地:
var events : [EKEvent] = // ...
sort(&events) {return $0.compareStartDateWithEvent($1) == .OrderedAscending}

这里有一个明显的模式,如果能够表达出来,就可以自动将选择器转换为 Swift 函数,但我不知道如何做到。 - matt

2
你可以通常使用内置的
func sort<T : Comparable>(inout array: [T])

但是如果您想使用 localizedCaseInsensitiveCompare:,您的代码可以直接使用 NSArray 进行翻译。


1
在Swift中-
let students: Set = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
let sortedStudents = students.sorted()
print(sortedStudents)
// Prints "["Abena", "Akosua", "Kofi", "Kweku", "Peter"]"

要将您的序列元素按降序排序,请将大于号(>)传递给sorted(isOrderedBefore:)方法。
let descendingStudents = students.sorted(isOrderedBefore: >)
print(descendingStudents)
// Prints "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接