Эквивалент Swift для макросов MIN и MAX

98

В C / Objective-C можно найти минимальное и максимальное значение между двумя числами, используя макросы MIN и MAX. Swift не поддерживает макросы, и похоже, что в языковой / базовой библиотеке нет эквивалентов. Если один идти с пользовательским решением, может быть основано на дженерики , как этот один ?

mxb
источник

Ответы:

125

minи maxуже определены в Swift:

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

Посмотрите эту замечательную статью о документированных и недокументированных встроенных функциях в Swift .

разъем
источник
2
Сожалею. Как вы узнали об этом? Я не вижу его ни в «Языке программирования Swift», ни в поиске документации Xcode6.
GoZoner
7
@GoZoner Иногда вам просто нужно набрать его в Xcode и проверить заголовок Swift. Если вы наберете let a : Int = 5и Command + Click Int, вы увидите интересные вещи!
Джек
Вау, рад что спросил! В лучшем случае я печатал a.и просматривал возможности завершения Xcode ... но «Command + Click» - это билет!
GoZoner
1
@GoZoner Autocomplete - тоже отличное место для поиска! К сожалению, на данный момент это очень шатко для Xcode 6 ...
Джек
36

Как уже отмечалось, Swift предоставляет maxи minфункционирует.

Пример (обновлен для 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 () имеет значение 0, поэтому, если ваши числа отрицательны, это не сработает
eonist 01
1
вы можете сделать maxNumber необязательным и заменить цикл for следующим образом: numbers.forEach {maxNumber = maxNumber! = nil? max (maxNumber!, $ 0): $ 0}
eonist 01
18

В Swift 5 max(_:_:)и min(_:_:)являются частью глобальных числовых функций . max(_:_:)имеет следующее объявление:

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

Вы можете использовать это с Ints:

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

Также отметим , что существуют и другие функции , которые вызываются max(_:_:_:_:)и min(_:_:_:_:)что позволяет сравнивать даже больше параметров. max(_:_:_:_:)имеет следующее объявление:

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

Вы можете использовать это с Floats:

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

Однако со Swift вы не ограничены в использовании max(_:_:)и его собратьях с числами. На самом деле, эти функции являются общими и могут принимать параметры любого типа , который соответствует Comparableпротоколу, это может быть String, Characterили один из пользовательских classили struct.

Таким образом, следующий пример кода Playground отлично работает:

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"

Кроме того, если вы хотите получить элемент min / max элементов, которые находятся внутри Array, a Set, a Dictionaryили любой другой последовательности Comparableэлементов, вы можете использовать методы max () или min () (см. Этот ответ о переполнении стека для получения дополнительной информации подробности).

Иману Пети
источник
1
Очень полезно, спасибо! Намного лучше, чем ответ выше, поскольку вы фактически даете пример использования, а не загадочный заголовок.
Cindeselia
14

Синтаксис SWIFT 4 немного изменился:

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

и

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

Поэтому, когда вы его используете, вы должны писать, как в этом примере:

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

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

Таким образом, вы получаете значение от 0 до 100, независимо от того, меньше ли оно 0 или больше 100.

wm.p1us
источник
2
Если вы получаете забавную ошибку компилятора в XCode 9, как я, говоря, что max () не существует, даже если вы явно передаете ему два Ints, затем измените его на Swift.max и вдруг ура, все станет лучше. Спасибо, wm.p1us!
xaphod
0

Попробуй это.

    let numbers = [2, 3, 10, 9, 14, 6]  
    print("Max = \(numbers.maxElement()) Min = \(numbers.minElement())")
SaRaVaNaN DM
источник