Equivalent Swift pour les macros MIN et MAX

98

En C / Objective-C, il est possible de trouver la valeur minimale et maximale entre deux nombres en utilisant les macros MIN et MAX. Swift ne prend pas en charge les macros et il semble qu'il n'y ait pas d'équivalents dans le langage / bibliothèque de base. Doit-on opter pour une solution personnalisée, peut-être basée sur des génériques comme celui- ci ?

mxb
la source

Réponses:

125

minet maxsont déjà définis dans Swift:

func max<T : Comparable>(x: T, y: T, rest: T...) -> T
func min<T : Comparable>(x: T, y: T, rest: T...) -> T

Voir cet excellent article sur les fonctions intégrées documentées et non documentées dans Swift .

Jack
la source
2
Désolé. Comment avez-vous appris cela? Je ne le vois pas dans 'The Swift Programming Language' ni dans une recherche de documentation Xcode6.
GoZoner
7
@GoZoner Parfois, il vous suffit de le taper dans Xcode et de vérifier l'en-tête Swift. Si vous tapez let a : Int = 5et Command + Cliquez sur Int, vous obtenez de voir des trucs sympas!
Jack
Wow, content d'avoir demandé! Au mieux, j'avais tapé a.et fait défiler les possibilités de complétion Xcode ... mais 'Command + Click' est le ticket!
GoZoner
1
@GoZoner Autocomplete est également un excellent endroit pour rechercher! Malheureusement, c'est très bancal pour Xcode 6 pour le moment ...
Jack
36

Comme indiqué, Swift fournit maxet minfonctionne.

Un exemple (mis à jour pour Swift 2.x).

let numbers = [ 1, 42, 5, 21 ]
var maxNumber = Int()

for number in numbers {
    maxNumber = max(maxNumber, number as Int)
}

print("the max number is \(maxNumber)")   // will be 42
Kyle Clegg
la source
Int () a la valeur de 0, donc si vos nombres sont négatifs, cela ne fonctionnera pas
eonist
1
vous pouvez rendre le maxNumber facultatif et remplacer la boucle for par ceci: numbers.forEach {maxNumber = maxNumber! = nil? max (maxNumber!, $ 0): $ 0}
eonist
18

Avec Swift 5, max(_:_:)et min(_:_:)font partie des fonctions numériques globales . max(_:_:)a la déclaration suivante:

func max<T>(_ x: T, _ y: T) -> T where T : Comparable

Vous pouvez l'utiliser comme ceci avec Ints:

let maxInt = max(5, 12) // returns 12

Notez également qu'il existe d'autres fonctions appelées max(_:_:_:_:)et min(_:_:_:_:)qui vous permettent de comparer encore plus de paramètres. max(_:_:_:_:)a la déclaration suivante:

func max<T>(_ x: T, _ y: T, _ z: T, _ rest: T...) -> T where T : Comparable

Vous pouvez l'utiliser comme ceci avec Floats:

let maxInt = max(12.0, 18.5, 21, 26, 32.9, 19.1) // returns 32.9

Avec Swift cependant, vous n'êtes pas limité à l'utilisation max(_:_:)et à ses frères et sœurs avec des chiffres. En fait, ces fonctions sont génériques et peuvent accepter n'importe quel type de paramètre conforme au Comparableprotocole, que ce soit String, Characterou l'un de vos fichiers classou struct.

Ainsi, l'exemple de code Playground suivant fonctionne parfaitement:

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 route1 = Route(distance: 4)
let route2 = Route(distance: 8)

let maxRoute = max(route1, route2)
print(maxRoute) // prints "Route with distance: 8"

De plus, si vous souhaitez obtenir l'élément min / max des éléments qui sont à l'intérieur d'une Array, a Set, a Dictionaryou toute autre séquence d' Comparableéléments, vous pouvez utiliser les méthodes max () ou min () (voir cette réponse Stack Overflow pour plus détails).

Imanou Petit
la source
1
Très utile, merci! Bien mieux que la réponse ci-dessus puisque vous donnez en fait un exemple d'utilisation, plutôt qu'un en-tête cryptique.
Cindeselia
14

La syntaxe de SWIFT 4 a un peu changé:

public func max<T>(_ x: T, _ y: T) -> T where T : Comparable
public func min<T>(_ x: T, _ y: T) -> T where T : Comparable

et

public func max<T>(_ x: T, _ y: T, _ z: T, _ rest: T...) -> T where T : Comparable
public func min<T>(_ x: T, _ y: T, _ z: T, _ rest: T...) -> T where T : Comparable

Ainsi, lorsque vous l'utilisez, vous devez écrire comme dans cet exemple:

let min = 0
let max = 100
let value = -1000

let currentValue = Swift.min(Swift.max(min, value), max)

Ainsi, vous obtenez la valeur de 0 à 100, peu importe qu'elle soit inférieure à 0 ou supérieure à 100.

wm.p1us
la source
2
Si vous obtenez une erreur de compilateur amusante dans XCode 9 comme moi, en disant que max () n'existe pas même lorsque vous le passez clairement deux Ints, changez-le en Swift.max et soudainement, les choses vont mieux. Merci wm.p1us!
xaphod
0

Essaye ça.

    let numbers = [2, 3, 10, 9, 14, 6]  
    print("Max = \(numbers.maxElement()) Min = \(numbers.minElement())")
SaRaVaNaN DM
la source