Equivalente rápido para macros MIN y MAX

97

En C / Objective-C es posible encontrar el valor mínimo y máximo entre dos números usando macros MIN y MAX. Swift no admite macros y parece que no hay equivalentes en la biblioteca de idioma / base. ¿Hay que ir con una solución personalizada, tal vez sobre la base de los genéricos como este uno ?

mxb
fuente

Respuestas:

124

miny maxya están definidos en Swift:

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

Vea este gran artículo sobre funciones integradas documentadas e indocumentadas en Swift .

Jack
fuente
2
Lo siento. ¿Cómo aprendiste esto? No lo veo en 'The Swift Programming Language' ni en una búsqueda de documentación de Xcode6.
GoZoner
7
@GoZoner A veces solo tienes que escribirlo en Xcode y ver el encabezado Swift. Si escribes let a : Int = 5y presionas Comando + clic Int, ¡podrás ver cosas interesantes!
Jack
¡Vaya, me alegro de haber preguntado! En el mejor de los casos, había estado escribiendo a.y desplazándome por las posibilidades de finalización de Xcode ... ¡pero 'Command + Click' es el boleto!
GoZoner
1
¡@GoZoner Autocompletar también es un gran lugar para buscar! Desafortunadamente, es muy raro para Xcode 6 en este momento ...
Jack
36

Como se señaló, Swift proporciona maxy minfunciona.

Un ejemplo (actualizado para 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
fuente
Int () tiene el valor de 0, por lo que si sus números son negativos, esto no funcionará
eonista
1
podría hacer que maxNumber sea opcional y reemplazar el bucle for con esto: numbers.forEach {maxNumber = maxNumber! = nil? max (maxNumber!, $ 0): $ 0}
eonist
18

Con Swift 5 max(_:_:)y min(_:_:)son parte de las funciones numéricas globales . max(_:_:)tiene la siguiente declaración:

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

Puedes usarlo así con Ints:

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

También tenga en cuenta que hay otras funciones llamadas max(_:_:_:_:)y min(_:_:_:_:)que le permite comparar aún más parámetros. max(_:_:_:_:)tiene la siguiente declaración:

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

Puedes usarlo así con Floats:

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

Sin embargo, con Swift, no está limitado al uso max(_:_:)y sus hermanos con números. De hecho, esas funciones son genéricas y pueden aceptar cualquier tipo de parámetro que se ajuste al Comparableprotocolo, ya sea String, Characteruno de sus personalizados classo struct.

Por lo tanto, el siguiente código de muestra de Playground funciona perfectamente:

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"

Además, si desea obtener el elemento min / max de los elementos que están dentro de una Array, a Set, a Dictionaryo cualquier otra secuencia de Comparableelementos, puede usar los métodos max () o min () (consulte esta respuesta de Stack Overflow para obtener más información) detalles).

Imanou Petit
fuente
1
¡Muy útil, gracias! Mucho mejor que la respuesta anterior, ya que en realidad da un ejemplo de uso, en lugar de un encabezado críptico.
Cindeselia
14

La sintaxis de SWIFT 4 cambió un poco:

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

y

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

Entonces, cuando lo use, debe escribir como en este ejemplo:

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

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

Entonces obtienes el valor de 0 a 100, no importa si está por debajo de 0 o por encima de 100.

wm.p1us
fuente
2
Si recibe un error de compilador divertido en XCode 9 como yo, diciendo que max () no existe incluso cuando claramente le pasa dos Ints, cámbielo a Swift.max y de repente ¡sí !, las cosas están mejor. ¡Gracias wm.p1us!
xaphod
0

Prueba esto.

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