Sorting Array in Swift3

前端 未结 3 2001
遥遥无期
遥遥无期 2021-02-02 01:39

In my code, I have a struct like the following:

struct Object {
    var name: String
    var count: Int

I am now creating an array of 10 Object

3条回答
  •  臣服心动
    2021-02-02 02:16

    If you want to sort alphabetically and then numerically, you can:

    var array = ["A2", "B7", "A4", "C3", "A1", "A10"]
    array.sort { $0.compare($1, options: .numeric) == .orderedAscending }
    

    That produces:

    ["A1", "A2", "A4", "A10", "B7", "C3"]

    I added A10 to your array, because without it, a simple alphabetic sort would have been sufficient. But I'm assuming you wanted A10 after A4, in which case the numeric comparison will do the job for you.


    You changed the example to be a struct with two properties. In that case, you can do something like:

    struct Foo {
        var name: String
        var count: Int
    }
    
    var array = [
        Foo(name:"A", count: 2),
        Foo(name:"B", count: 7),
        Foo(name:"A", count: 7),
        Foo(name:"C", count: 3),
        Foo(name:"A", count: 1),
        Foo(name:"A", count: 10)
    ]
    
    array.sort { (object1, object2) -> Bool in
        if object1.name == object2.name {
            return object1.count < object2.count
        } else {
            return object1.name < object2.name
        }
    }
    

    Or, more concisely:

    array.sort { $0.name == $1.name ? $0.count < $1.count : $0.name < $1.name }
    

    Or

    array.sort { ($0.name, $0.count) < ($1.name, $1.count) }
    

    Note, rather than putting this logic in the closure, I'd actually make Foo conform to Comparable:

    struct Foo {
        var name: String
        var count: Int
    }
    
    extension Foo: Equatable {
        static func ==(lhs: Foo, rhs: Foo) -> Bool {
            return (lhs.name, lhs.count) == (rhs.name, rhs.count)
        }
    }
    
    extension Foo: Comparable {
        static func <(lhs: Foo, rhs: Foo) -> Bool {
            return (lhs.name, lhs.count) < (rhs.name, rhs.count)
        }
    }
    

    This keeps the comparison logic nicely encapsulated within the Foo type, where it belongs.

    Then you can just do the following to sort in place:

    var array = ...
    array.sort()
    

    Or, alternatively, you can return a new array if you don't want to sort the original one in place:

    let array = ...
    let sortedArray = array.sorted()
    

提交回复
热议问题