Швидкий еквівалент для макросів MIN і MAX


97

У C / Objective-C можна знайти мінімальне та максимальне значення між двома номерами, використовуючи макроси MIN та MAX. Swift не підтримує макроси, і здається, що в мовній / базовій бібліотеці немає еквівалентів. Якщо один йти з призначеним для користувача рішенням, може бути засноване на дженерики , як цей один ?

Відповіді:


124

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
Вибачте. Як ви це дізналися? Я не бачу цього в "Швидкій мові програмування", ні в пошуку документації Xcode6.
GoZoner

7
@GoZoner Іноді потрібно просто набрати його в Xcode і перевірити заголовок Swift. Якщо ви наберете let a : Int = 5та Command + натисніть Int, ви побачите цікаві речі!
Джек

Нічого собі, рада, що я запитав! У кращому випадку я набирав a.та прокручував можливості заповнення Xcode ... але "Command + Click" - це квиток!
GoZoner

1
@GoZoner Автозаповнення - чудове місце для пошуку! На жаль, на даний момент це дуже приємно для 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, тому якщо ваші цифри від'ємні, це не працюватиме
еоніст

1
ви можете зробити maxNumber необов’язковим і замінити цикл for на цей: numbers.forEach {maxNumber = maxNumber! = nil? max (maxNumber!, $ 0): $ 0}
eonist

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

Зі Свіфтом, однак, ви не обмежені у використанні max(_:_:)та його братів та сестер із числами. Насправді ці функції є загальними і можуть приймати будь-який тип параметрів, який відповідає Comparableпротоколу, може бути String, Characterабо одним із ваших власних classабоstruct .

Таким чином, наступний зразок коду дитячої площадки прекрасно працює:

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 елементів, які знаходяться всередині елементів Arraya, 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.


2
Якщо ви отримуєте помилкову помилку компілятора в XCode 9, як я, кажучи, що max () не існує навіть тоді, коли ви чітко пропустите її два Intс, потім змініть її на Swift.max і раптом так, все краще. Дякую wm.p1us!
xaphod

0

Спробуйте це.

    let numbers = [2, 3, 10, 9, 14, 6]  
    print("Max = \(numbers.maxElement()) Min = \(numbers.minElement())")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.