Swift how to sort array of custom objects by prope

2018-12-31 05:57发布

lets say we have a custom class named imageFile and this class contains two properties.

class imageFile  {
    var fileName = String()
    var fileID = Int()
}

lots of them stored in Array

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)

question is: how can i sort images array by 'fileID' ASC or DESC?

15条回答
余欢
2楼-- · 2018-12-31 06:26

You can also do something like

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

so your images array will be stored as sorted

查看更多
泪湿衣
3楼-- · 2018-12-31 06:26

If you are not using custom objects, but value types instead that implements Comparable protocol (Int, String etc..) you can simply do this:

myArray.sort(>) //sort descending order

An example:

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
查看更多
裙下三千臣
4楼-- · 2018-12-31 06:29

Two alternatives

1) Ordering the original array with sortInPlace

self.assignments.sortInPlace({ $0.order < $1.order })
self.printAssignments(assignments)

2) Using an alternative array to store the ordered array

var assignmentsO = [Assignment] ()
assignmentsO = self.assignments.sort({ $0.order < $1.order })
self.printAssignments(assignmentsO)
查看更多
闭嘴吧你
5楼-- · 2018-12-31 06:30

First, declare your Array as a typed array so that you can call methods when you iterate:

var images : [imageFile] = []

Then you can simply do:

Swift 2

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

Swift 3 & 4

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

The example above gives desc sort order

查看更多
其实,你不懂
6楼-- · 2018-12-31 06:35

Swift 2 through 4

The original answer sought to sort an array of custom objects using some property. Below I will show you a few handy ways to do this same behavior w/ swift data structures!

Little things outta the way, I changed ImageFile ever so slightly. With that in mind, I create an array with three image files. Notice that metadata is an optional value, passing in nil as a parameter is expected.

 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 has a property named size. For the following examples I will show you how to use sort operations w/ properties like size.

smallest to biggest size (<)

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

biggest to smallest (>)

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

Next we'll sort using the String property name. In the same manner, use sort to compare strings. But notice the inner block returns a comparison result. This result will define 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
    }

Next is my favorite way to sort, in many cases one will have optional properties. Now don't worry, we're going to sort in the same manner as above except we have to handle nil! In production;

I used this code to force all instances in my array with nil property values to be last. Then order metadata using the assumed unwrapped values.

    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
    }

It is possible to have a secondary sort for optionals. For example; one could show images with metadata and ordered by size.

查看更多
旧人旧事旧时光
7楼-- · 2018-12-31 06:36

Swift 3

people = people.sorted(by: { $0.email > $1.email })
查看更多
登录 后发表回答