Correct way to find max in an Array in Swift

前端 未结 12 1808
一整个雨季
一整个雨季 2020-11-29 18:05

I\'ve so far got a simple (but potentially expensive) way:

var myMax = sort(myArray,>)[0]

And how I was taught to do it at school:

12条回答
  •  独厮守ぢ
    2020-11-29 18:37

    With Swift 5, Array, like other Sequence Protocol conforming objects (Dictionary, Set, etc), has two methods called max() and max(by:) that return the maximum element in the sequence or nil if the sequence is empty.


    #1. Using Array's max() method

    If the element type inside your sequence conforms to Comparable protocol (may it be String, Float, Character or one of your custom class or struct), you will be able to use max() that has the following declaration:

    @warn_unqualified_access func max() -> Element?
    

    Returns the maximum element in the sequence.

    The following Playground codes show to use max():

    let intMax = [12, 15, 6].max()
    let stringMax = ["bike", "car", "boat"].max()
    
    print(String(describing: intMax)) // prints: Optional(15)
    print(String(describing: stringMax)) // prints: Optional("car")
    
    class Route: Comparable, CustomStringConvertible {
    
        let distance: Int
        var description: String { return "Route with distance: \(distance)" }
    
        init(distance: Int) {
            self.distance = distance
        }
    
        static func ==(lhs: Route, rhs: Route) -> Bool {
            return lhs.distance == rhs.distance
        }
    
        static func <(lhs: Route, rhs: Route) -> Bool {
            return lhs.distance < rhs.distance
        }
    
    }
    
    let routes = [
        Route(distance: 20),
        Route(distance: 30),
        Route(distance: 10)
    ]
    
    let maxRoute = routes.max()
    print(String(describing: maxRoute)) // prints: Optional(Route with distance: 30)
    

    #2. Using Array's max(by:) method

    If the element type inside your sequence does not conform to Comparable protocol, you will have to use max(by:) that has the following declaration:

    @warn_unqualified_access func max(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element?
    

    Returns the maximum element in the sequence, using the given predicate as the comparison between elements.

    The following Playground codes show to use max(by:):

    let dictionary = ["Boat" : 15, "Car" : 20, "Bike" : 40]
    
    let keyMaxElement = dictionary.max(by: { (a, b) -> Bool in
        return a.key < b.key
    })
    
    let valueMaxElement = dictionary.max(by: { (a, b) -> Bool in
        return a.value < b.value
    })
    
    print(String(describing: keyMaxElement)) // prints: Optional(("Car", 20))
    print(String(describing: valueMaxElement)) // prints: Optional(("Bike", 40))
    
    class Route: CustomStringConvertible {
    
        let distance: Int
        var description: String { return "Route with distance: \(distance)" }
    
        init(distance: Int) {
            self.distance = distance
        }
    
    }
    
    let routes = [
        Route(distance: 20),
        Route(distance: 30),
        Route(distance: 10)
    ]
    
    let maxRoute = routes.max(by: { (a, b) -> Bool in
        return a.distance < b.distance
    })
    
    print(String(describing: maxRoute)) // prints: Optional(Route with distance: 30)
    

提交回复
热议问题