假设我们有一个名为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 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
    }

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

其他回答

如果您想对自定义对象的原始数组进行排序。在Swift 2.1中有另一种方法

var myCustomerArray = [Customer]()
myCustomerArray.sortInPlace {(customer1:Customer, customer2:Customer) -> Bool in
    customer1.id < customer2.id
}

其中id为整数。您也可以对String属性使用相同的<操作符。

你可以通过下面的例子了解更多关于它的用法: Swift2:附近的顾客

斯威夫特3、4、5所示

    struct imageFile  {
        var fileName = String()
        var fileID = Int()
    }
    
    //append objects like this
    var arrImages = [imageFile]()
    arrImages.append(.init(fileName: "Hello1.png", fileID: 1))
    arrImages.append(.init(fileName: "Hello3.png", fileID: 3))
    arrImages.append(.init(fileName: "Hello2.png",fileID: 2))

    
    //array sorting using below code
    let sortImagesArr = arrImages.sorted(by: {$0.fileID < $1.fileID})
    print(sortImagesArr)
    
    //output
    
    imageFile(fileName: "Hello1.png", fileID: 1),
    imageFile(fileName: "Hello2.png", fileID: 2),
    imageFile(fileName: "Hello3.png", fileID: 3)

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
}

[为Swift 3更新了sort(by:)]这,利用一个尾随闭包:

images.sorted { $0.fileID < $1.fileID }

根据ASC或DESC分别使用<或>。如果你想修改图像数组,那么使用以下命令:

images.sort { $0.fileID < $1.fileID }

如果你要重复这样做,并且更喜欢定义一个函数,一种方法是:

func sorterForFileIDASC(this:imageFile, that:imageFile) -> Bool {
  return this.fileID < that.fileID
}

然后用as:

images.sort(by: sorterForFileIDASC)

几乎每个人都给出了如何直接,让我来展示一下演变:

你可以使用Array的实例方法:

// general form of closure
images.sortInPlace({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })

// types of closure's parameters and return value can be inferred by Swift, so they are omitted along with the return arrow (->)
images.sortInPlace({ image1, image2 in return image1.fileID > image2.fileID })

// Single-expression closures can implicitly return the result of their single expression by omitting the "return" keyword
images.sortInPlace({ image1, image2 in image1.fileID > image2.fileID })

// closure's argument list along with "in" keyword can be omitted, $0, $1, $2, and so on are used to refer the closure's first, second, third arguments and so on
images.sortInPlace({ $0.fileID > $1.fileID })

// the simplification of the closure is the same
images = images.sort({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in image1.fileID > image2.fileID })
images = images.sort({ $0.fileID > $1.fileID })

关于排序的工作原理的详细解释,请参见排序函数。