Swift how to sort array of custom objects by property value

前端 未结 18 2163
逝去的感伤
逝去的感伤 2020-11-22 02:12

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

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


        
相关标签:
18条回答
  • 2020-11-22 02:43

    Sort using KeyPath

    you can sort by KeyPath like this:

    myArray.sorted(by: \.fileName, <) /* using `<` for ascending sorting */
    

    By implementing this little helpful extension.

    extension Collection{
        func sorted<Value: Comparable>(
            by keyPath: KeyPath<Element, Value>,
            _ comparator: (_ lhs: Value, _ rhs: Value) -> Bool) -> [Element] {
            sorted { comparator($0[keyPath: keyPath], $1[keyPath: keyPath]) }
        }
    }
    

    Hope Swift add this in the near future in the core of the language.

    0 讨论(0)
  • 2020-11-22 02:44

    Nearly everyone gives how directly, let me show the evolvement:

    you can use the instance methods of 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 })
    

    For elaborate explanation about the working principle of sort, see The Sorted Function.

    0 讨论(0)
  • 2020-11-22 02:45
    var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
    
    students.sort(by: >)
    
    print(students)
    

    Prints : "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"

    0 讨论(0)
  • 2020-11-22 02:46

    [Updated for Swift 3 with sort(by:)] This, exploiting a trailing closure:

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

    where you use < or > depending on ASC or DESC, respectively. If you want to modify the images array, then use the following:

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

    If you are going to do this repeatedly and prefer to define a function, one way is:

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

    and then use as:

    images.sort(by: sorterForFileIDASC)
    
    0 讨论(0)
  • 2020-11-22 02:46

    If you are going to be sorting this array in more than one place, it may make sense to make your array type 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]"
    
    0 讨论(0)
  • 2020-11-22 02:48

    I do it like this and it works:

    var images = [imageFile]() images.sorted(by: {$0.fileID.compare($1.fileID) == .orderedAscending })

    0 讨论(0)
提交回复
热议问题