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 ?

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 .


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

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).


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.


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())")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.