假设我们有一个名为imageFile的自定义类,这个类包含两个属性:
class imageFile {
var fileName = String()
var fileID = Int()
}
很多都存储在一个数组中:
var images : Array = []
var aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 101
images.append(aImage)
aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 202
images.append(aImage)
我如何排序的图像数组由'fileID'升序或降序?
Swift 4.0, 4.1和4.2:
首先,我创建了imageFile类型的可变数组,如下所示
var arr = [imageFile]()
创建类型为imageFile的可变对象图像,并为属性赋值,如下所示
var image = imageFile()
image.fileId = 14
image.fileName = "A"
现在,将这个对象追加到数组arr
arr.append(image)
现在,将不同的属性分配给相同的可变对象,即图像
image = imageFile()
image.fileId = 13
image.fileName = "B"
现在,再次将image object追加到数组arr中
arr.append(image)
现在,我们将对数组arr对象中的fileId属性应用升序。使用<符号按升序排列
arr = arr.sorted(by: {$0.fileId < $1.fileId}) // arr has all objects in Ascending order
print("sorted array is",arr[0].fileId)// sorted array is 13
print("sorted array is",arr[1].fileId)//sorted array is 14
现在,我们将在数组arr对象中的fileId属性上应用降序。降序使用>符号
arr = arr.sorted(by: {$0.fileId > $1.fileId}) // arr has all objects in Descending order
print("Unsorted array is",arr[0].fileId)// Unsorted array is 14
print("Unsorted array is",arr[1].fileId)// Unsorted array is 13
在Swift 4.1和4.2中,用于排序使用
let sortedArr = arr.sorted { (id1, id2) -> Bool in
return id1.fileId < id2.fileId // Use > for Descending order
}
如果你要在多个地方对这个数组排序,让你的数组类型Comparable是有意义的。
class MyImageType: Comparable, Printable {
var fileID: Int
// For Printable
var description: String {
get {
return "ID: \(fileID)"
}
}
init(fileID: Int) {
self.fileID = fileID
}
}
// For Comparable
func <(left: MyImageType, right: MyImageType) -> Bool {
return left.fileID < right.fileID
}
// For Comparable
func ==(left: MyImageType, right: MyImageType) -> Bool {
return left.fileID == right.fileID
}
let one = MyImageType(fileID: 1)
let two = MyImageType(fileID: 2)
let twoA = MyImageType(fileID: 2)
let three = MyImageType(fileID: 3)
let a1 = [one, three, two]
// return a sorted array
println(sorted(a1)) // "[ID: 1, ID: 2, ID: 3]"
var a2 = [two, one, twoA, three]
// sort the array 'in place'
sort(&a2)
println(a2) // "[ID: 1, ID: 2, ID: 2, ID: 3]"
如果数组元素符合Comparable,那么你可以简单地使用函数语法:
array.sort(by: <)
如果你是基于自定义类型排序,你所需要做的就是实现<运算符:
class ImageFile {
let fileName: String
let fileID: Int
let fileSize: Int
static func < (left: ImageFile, right: ImageFile) -> Bool {
return left.fileID < right.fileID
}
}
但是,有时您不需要一种标准的比较imagefile的方法。也许在某些上下文中,您希望基于fileID对图像进行排序,而在其他地方,您希望基于fileSize对图像进行排序。对于动态比较,您有两个选项。
(by: sorted)
images = images.sorted(by: { a, b in
// Return true if `a` belongs before `b` in the sorted array
if a.fileID < b.fileID { return true }
if a.fileID > b.fileID { return false }
// Break ties by comparing file sizes
return a.fileSize > b.fileSize
})
你可以使用尾随闭包来简化语法:
images.sorted { ... }
但是手动输入if语句会导致代码很长(如果我们想通过基于文件名排序来打破文件大小的束缚,我们将会有一个相当长的if厄运链)。我们可以通过使用全新的SortComparator协议(macOS 12+, iOS 15+)来避免这种语法:
排序(使用:)
files = files.sorted(using: [
KeyPathComparator(\.fileID, order: .forward),
KeyPathComparator(\.fileSize, order: .reverse),
])
这段代码根据文件ID()对文件进行排序。Forward表示升序),并根据文件大小(。反向意味着下降)。\。fileID语法是我们指定关键路径的方式。您可以根据需要扩展比较器列表。
如果你不使用自定义对象,而是使用值类型来实现可比协议(Int, String等),你可以简单地这样做:
myArray.sort(>) //sort descending order
一个例子:
struct MyStruct: Comparable {
var name = "Untitled"
}
func <(lhs: MyStruct, rhs: MyStruct) -> Bool {
return lhs.name < rhs.name
}
// Implementation of == required by Equatable
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
return lhs.name == rhs.name
}
let value1 = MyStruct()
var value2 = MyStruct()
value2.name = "A New Name"
var anArray:[MyStruct] = []
anArray.append(value1)
anArray.append(value2)
anArray.sort(>) // This will sort the array in descending order