Szybki odpowiednik makr MIN i MAX

97

W C / Objective-C można znaleźć minimalną i maksymalną wartość między dwiema liczbami za pomocą makr MIN i MAX. Swift nie obsługuje makr i wydaje się, że nie ma odpowiedników w bibliotece językowej / podstawowej. Trzeba iść z niestandardowego rozwiązania, może na podstawie generycznych jak ten jeden ?

mxb
źródło

Odpowiedzi:

124

mini maxsą już zdefiniowane w Swift:

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

Zobacz ten wspaniały opis udokumentowanych i nieudokumentowanych funkcji wbudowanych w Swift .

Jacek
źródło
2
Przepraszam. Jak się tego nauczyłeś? Nie widzę tego w „Swift Programming Language” ani w wyszukiwaniu dokumentacji Xcode6.
GoZoner,
7
@GoZoner Czasami wystarczy wpisać go w Xcode i sprawdzić nagłówek Swift. Jeśli napiszesz let a : Int = 5i naciśniesz Command + kliknięcie Int, zobaczysz fajne rzeczy!
Jack
Wow, cieszę się, że zapytałem! W najlepszym przypadku pisałem a.i przewijałem opcje uzupełniania Xcode ... ale „Command + Click” to bilet!
GoZoner,
1
@GoZoner Autocomplete to także świetne miejsce do wyszukiwania! Niestety, w tej chwili jest bardzo niepewny dla Xcode 6 ...
Jack
36

Jak wskazano, Swift zapewnia maxi minfunkcjonuje.

Przykład (zaktualizowany do wersji 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
źródło
Int () ma wartość 0, więc jeśli twoje liczby są ujemne, to nie zadziała
eonista
1
możesz uczynić maxNumber opcjonalnym i zamienić pętlę for na to: numbers.forEach {maxNumber = maxNumber! = nil? max (maxNumber!, $ 0): $ 0}
eonista
18

Z Swift 5 max(_:_:)i min(_:_:)są częścią Global Numeric Functions . max(_:_:)posiada następującą deklarację:

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

Możesz go używać w ten sposób z Ints:

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

Należy również pamiętać, że istnieją inne funkcje wywoływane max(_:_:_:_:)i min(_:_:_:_:)że pozwala porównać nawet więcej parametrów. max(_:_:_:_:)posiada następującą deklarację:

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

Możesz go używać w ten sposób z Floats:

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

Jednak dzięki Swift nie jesteś ograniczony do używania max(_:_:)i jego rodzeństwa z liczbami. W rzeczywistości te funkcje są ogólne i mogą akceptować dowolny typ parametru, który jest zgodny z Comparableprotokołem, może to być String, Characterlub jeden z niestandardowych classlub struct.

W związku z tym następujący przykładowy kod Playground działa idealnie:

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"

Ponadto, jeśli chcesz uzyskać element min / max elementów, które znajdują się wewnątrz sekwencji elementów an Array, a Set, a Dictionarylub dowolnej innej sekwencji Comparable, możesz użyć metod max () lub min () (zobacz odpowiedź przepełnienia stosu, aby uzyskać więcej informacji Detale).

Imanou Petit
źródło
1
Bardzo pomocne, dzięki! Znacznie lepiej niż powyższa odpowiedź, ponieważ w rzeczywistości podajesz przykład użycia, a nie tajemniczy nagłówek.
Cindeselia
14

Składnia SWIFT 4 nieco się zmieniła:

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

i

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

Więc kiedy go używasz, powinieneś napisać jak w tym przykładzie:

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

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

Więc otrzymujesz wartość od 0 do 100, nie ma znaczenia, czy jest poniżej 0 czy powyżej 100.

wm.p1us
źródło
2
Jeśli otrzymujesz zabawny błąd kompilatora w XCode 9, tak jak ja, mówiąc, że max () nie istnieje, nawet jeśli przejdziesz przez dwie Intsekundy, to zmień go na Swift.max i nagle tak, wszystko jest lepsze. Dzięki wm.p1us!
xaphod
0

Spróbuj tego.

    let numbers = [2, 3, 10, 9, 14, 6]  
    print("Max = \(numbers.maxElement()) Min = \(numbers.minElement())")
SaRaVaNaN DM
źródło