假设我们有一个名为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'升序或降序?


当前回答

首先,将Array声明为类型化数组,以便在迭代时调用方法:

var images : [imageFile] = []

然后你可以简单地做:

斯威夫特2

images.sorted({ $0.fileID > $1.fileID })

斯威夫特3

images.sorted(by: { $0.fileID > $1.fileID })

斯威夫特5

images.sorted { $0.fileId > $1.fileID }

上面的例子按降序给出了结果。

其他回答

Swift 2到4

最初的答案寻求使用某些属性对自定义对象数组进行排序。下面我将向您展示一些使用swift数据结构实现相同行为的简便方法!

我稍微改变了ImageFile。考虑到这一点,我创建了一个包含三个图像文件的数组。注意,元数据是一个可选值,需要传入nil作为参数。

 struct ImageFile {
      var name: String
      var metadata: String?
      var size: Int
    }

    var images: [ImageFile] = [ImageFile(name: "HelloWorld", metadata: nil, size: 256), ImageFile(name: "Traveling Salesmen", metadata: "uh this is huge", size: 1024), ImageFile(name: "Slack", metadata: "what's in this stuff?", size: 2048) ]

ImageFile有一个名为size的属性。对于下面的例子,我将向您展示如何使用排序操作w/属性,如大小。

最小到最大的大小(<)

    let sizeSmallestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size < next.size
    }

从最大到最小(>)

    let sizeBiggestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size > next.size
    }

接下来,我们将使用String属性名进行排序。以同样的方式,使用sort来比较字符串。但是请注意,内部块返回一个比较结果。这个结果将定义排序。

a - z (.orderedAscending)

    let nameAscendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedAscending
    }

Z-A (.orderedDescending)

    let nameDescendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedDescending
    }

接下来是我最喜欢的排序方式,在许多情况下,一个将有可选的属性。现在不用担心,我们将以与上面相同的方式排序,除了我们必须处理nil!在生产;

我使用这段代码强制数组中具有nil属性值的所有实例放在最后。然后使用假设的未包装值对元数据进行排序。

    let metadataFirst = images.sorted { (initial, next) -> Bool in
      guard initial.metadata != nil else { return true }
      guard next.metadata != nil else { return true }
      return initial.metadata!.compare(next.metadata!) == .orderedAscending
    }

可以为可选项设置二级排序。例如;可以显示带有元数据并按大小排序的图像。

如果数组元素符合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

斯威夫特3

people = people.sorted(by: { $0.email > $1.email })

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
}