Vind min/max waarde in Swift Array

Hoe kan ik de minimum- en maximumwaarden vinden aan de hand van een reeks Swift-numerieke waarden?

Ik heb tot nu toe een eenvoudige (maar potentieel dure) manier:

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

En hoe ik het op school heb geleerd:

var myMax = 0
for i in 0..myArray.count {
    if (myArray[i] > myMax){myMax = myArray[i]}
}

Is er een betere manier om de minimum- of maximumwaarde uit een integer-array in Swift te halen? Idealiter is dat één regel, zoals Ruby’s .minen .max.


Antwoord 1, autoriteit 100%

Gegeven:

let numbers = [1, 2, 3, 4, 5]

Swift 3:

numbers.min() // equals 1
numbers.max() // equals 5

Swift 2:

numbers.minElement() // equals 1
numbers.maxElement() // equals 5

Antwoord 2, autoriteit 31%

Om de min en max waarden van een array zelf te berekenen, kun je reducegebruiken. Dit was een belangrijke oplossing voordat .min()en .max()in Swift verschenen.


Gebruik de almachtige reduce:

let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, { max($0, $1) })

Ook:

let numMin = nums.reduce(Int.max, { min($0, $1) })

reduceneemt een eerste waarde die de initiële waarde is voor een interne accumulatorvariabele, past vervolgens de doorgegeven functie (hier is het anoniem) toe op de accumulator en elk element van de array achtereenvolgens, en slaat op de nieuwe waarde in de accumulator. De laatste accumulatorwaarde wordt dan geretourneerd.


Antwoord 3, autoriteit 14%

Met Swift 5, Array, zoals andere SequenceProtocol-conforme objecten (Dictionary, Set, enz.) , heeft twee methoden genaamd max()en max(by:)die het maximum element in de reeks retourneren of nilals de reeks leeg is .


#1. Met behulp van Array‘s max()methode

Als het elementtype in uw reeks voldoet aan het Comparable-protocol (mag het String, Float, Characterof een van uw aangepaste klassen of struct), kunt u max()gebruiken met de volgende verklaring:

@warn_unqualified_access func max() -> Element?

Retourneert het maximum element in de reeks.

De volgende Playground-codes geven aan dat je max()moet gebruiken:

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. Met behulp van Array‘s max(by:)methode

Als het elementtype in uw reeks niet voldoet aan het Comparable-protocol, moet u max(by:)gebruiken met de volgende verklaring:

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

Retourneert het maximale element in de reeks, waarbij het gegeven predikaat wordt gebruikt als vergelijking tussen elementen.

De volgende Playground-codes geven aan dat je max(by:)moet gebruiken:

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)

Antwoord 4, autoriteit 5%

De andere antwoorden zijn allemaal correct, maar vergeet niet dat u ook verzamelingsoperatoren kunt gebruiken, als volgt:

var list = [1, 2, 3, 4]
var max: Int = (list as AnyObject).valueForKeyPath("@max.self") as Int

je kunt het gemiddelde ook op dezelfde manier vinden:

var avg: Double = (list as AnyObject).valueForKeyPath("@avg.self") as Double

Deze syntaxis is misschien minder duidelijk dan sommige van de andere oplossingen, maar het is interessant om te zien dat -valueForKeyPath:nog steeds kan worden gebruikt 🙂


Antwoord 5, autoriteit 3%

U kunt gebruiken met reduce:

let randomNumbers = [4, 7, 1, 9, 6, 5, 6, 9]
let maxNumber = randomNumbers.reduce(randomNumbers[0]) { $0 > $1 ? $0 : $1 } //result is 9

Antwoord 6, autoriteit 2%

Swift 3.0

Je kunt deze code programmatisch proberen.

func getSmallAndGreatestNumber() -> Void {
    let numbers = [145, 206, 116, 809, 540, 176]
    var i = 0
    var largest = numbers[0]
    var small = numbers[0]
    while i < numbers.count{
        if (numbers[i] > largest) {
            largest = numbers[i]
        }
        if (numbers[i] < small) {
            small = numbers[i]
        }
        i = i + 1
    }
    print("Maximum Number ====================\(largest)")// 809
    print("Minimum Number ====================\(small)")// 116
}

Antwoord 7

Met Swift 1.2 (en misschien eerder) moet je nu het volgende gebruiken:

let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, combine: { max($0, $1) })

Voor het werken met dubbele waarden heb ik zoiets als dit gebruikt:

let nums = [1.3, 6.2, 3.6, 9.7, 4.9, 6.3];
let numMax = nums.reduce(-Double.infinity, combine: { max($0, $1) })

8

U kunt uw array ook sorteren en vervolgens array.firstof array.last

gebruiken

Other episodes