Equivalente Swift para macros MIN e MAX

97

Em C / Objective-C é possível encontrar o valor mínimo e máximo entre dois números usando as macros MIN e MAX. O Swift não suporta macros e parece que não há equivalentes na linguagem / biblioteca base. Se um ir com uma solução personalizada, talvez baseada em genéricos como este um ?

mxb
fonte

Respostas:

124

mine maxjá estão definidos em Swift:

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

Veja este ótimo artigo sobre funções embutidas documentadas e não documentadas no Swift .

Jack
fonte
2
Desculpe. Como você aprendeu isso? Eu não vejo isso em 'The Swift Programming Language' nem em uma pesquisa de documentação do Xcode6.
GoZoner de
7
@GoZoner Às vezes você só precisa digitá-lo no Xcode e verificar o cabeçalho do Swift. Se você digitar let a : Int = 5e Command + Click Int, verá coisas legais!
Jack
Uau, que bom que perguntei! Na melhor das hipóteses, eu estava digitando a.e percorrendo as possibilidades de preenchimento do Xcode ... mas 'Command + Click' é o ingresso!
GoZoner de
1
@GoZoner Autocomplete é um ótimo lugar para pesquisar também! Infelizmente, está muito difícil para o Xcode 6 no momento ...
Jack
36

Como apontado, o Swift fornece maxe minfunções.

Um exemplo (atualizado 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
fonte
Int () tem o valor 0, portanto, se seus números forem negativos, isso não funcionará
eonist 01 de
1
você poderia tornar o maxNumber opcional e substituir o loop for por este: numbers.forEach {maxNumber = maxNumber! = nil? max (maxNumber!, $ 0): $ 0}
eonista de
18

Com o Swift 5, max(_:_:)e min(_:_:)fazem parte das Funções Numéricas Globais . max(_:_:)tem a seguinte declaração:

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

Você pode usá-lo assim com Ints:

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

Observe também que existem outras funções chamadas max(_:_:_:_:)e min(_:_:_:_:)isso permite que você compare ainda mais parâmetros. max(_:_:_:_:)tem a seguinte declaração:

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

Você pode usá-lo assim com Floats:

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

Com o Swift, no entanto, você não está limitado a usar max(_:_:)e seus irmãos com números. Na verdade, essas funções são genéricas e podem aceitar qualquer tipo de parâmetro que esteja em conformidade com o Comparableprotocolo, seja ele String, Characterou um de seus customizados classou struct.

Assim, o seguinte código de amostra do Playground funciona perfeitamente:

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"

Além disso, se você deseja obter o elemento min / max de elementos que estão dentro de uma Array, a Set, a Dictionaryou qualquer outra sequência de Comparableelementos, você pode usar os métodos max () ou min () (veja esta resposta Stack Overflow para mais detalhes).

Imanou Petit
fonte
1
Muito útil, obrigado! Muito melhor do que a resposta acima, já que você realmente dá um exemplo de uso, em vez de um cabeçalho enigmático.
Cindeselia
14

A sintaxe do SWIFT 4 mudou um pouco:

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

e

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

Então, ao usá-lo, você deve escrever como neste exemplo:

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

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

Portanto, você obtém o valor de 0 a 100, não importa se é inferior a 0 ou superior a 100.

wm.p1us
fonte
2
Se você está recebendo um erro divertido do compilador no XCode 9 como eu, dizendo que max () não existe mesmo quando você claramente passa dois Ints, então mude para Swift.max e de repente yay, as coisas estão melhores. Obrigado wm.p1us!
xaphod
0

Experimente isso.

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