Swift의 배열에서 최대 값을 찾는 올바른 방법


121

지금까지 간단하지만 비용이 많이 드는 방법이 있습니다.

var myMax = sort(myArray,>)[0]

그리고 학교에서 어떻게 배웠는지 :

var myMax = 0
for i in 0..myArray.count {
    if (myArray[i] > myMax){myMax = myArray[i]}
}

Swift의 정수 배열에서 최대 값을 얻는 더 좋은 방법이 있습니까? 이상적으로는 Ruby와 같은 한 줄의.max


확장을 작성합니다.
gnasher729 2014-06-04

예, 한 줄 : maxElement(myArray). 아래에서 현재 두 번째 답변 (Rudolf Adamkovic의)이 무엇인지 확인하세요.
leekaiinthesky


@mattymcgee 수락 된 답변을 업데이트했습니다.
Charlie Egan

답변:


299

주어진:

let numbers = [1, 2, 3, 4, 5]

스위프트 3 :

numbers.min() // equals 1
numbers.max() // equals 5

스위프트 2 :

numbers.minElement() // equals 1
numbers.maxElement() // equals 5

2
Comparable개체 에서만 NSDecimalNumber작동하므로 예를 들어 작동하지 않습니다.
Michał Hernas 2015

2
나뿐입니까 아니면 이러한 기능이 Swift 2에 존재하지 않습니까?
Liron Yahdav 2015 년

@LironYahdav 그들은 이제 방법입니다. 결정된. 감사!
Rudolf Adamkovič 2015 년

2
Swift 3에서는 이러한 이름이 simply min()max().
jemmons jul

1
@Jezzamon 아니요. Swift 3에서 메서드 minElementmaxElement이름이 minmax. 참조 : github.com/apple/swift-evolution/blob/master/proposals/… 무료 기능 minmax여전히 존재 하기 때문에 혼란을 이해 합니다. 예를 들어, gist.github.com/lorentey/d679064cb29df4558534d619319a1d9e
jemmons

95

업데이트 : 이것은maxElement Swift에 나타난 이후로 받아 들여진 대답 일 것입니다 .


전능자를 사용하십시오 reduce:

let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, { max($0, $1) })

비슷하게:

let numMin = nums.reduce(Int.max, { min($0, $1) })

reduce내부 누산기 변수의 초기 값인 첫 번째 값을 취한 다음 전달 된 함수 (여기서는 익명)를 누산기와 배열의 각 요소에 연속적으로 적용하고 누산기에 새 값을 저장합니다. 그런 다음 마지막 누산기 값이 반환됩니다.


1
완벽 해, 내가 찾던 바로 그것. iBook에는없는 것들이 많이 있습니다!
Charlie Egan

2
그것들은 일반적인 함수형 프로그래밍 기술 일 뿐이며 Swift에만 국한된 것은 아닙니다.
Jean-Philippe Pellet

10
장 - PhilippePellet @ 당신은 실제로 단지이를 단순화 할 수 nums.reduce(Int.min, max)있기 때문에 max'의 프로토 타입이 이미 유형과 일치 reduce기대
drewag

이것이 복식 배열에서 작동하지 않는 이유가 있습니까?
Nicholas

3
최소 / 최대 함수 서명은 combine : 매개 변수 서명과 일치하므로 함수 자체를 전달할 수 있습니다.let numMax = nums.reduce(Int.min, combine: max)
Leslie Godwin

38

스위프트 (5), Array기타와 같은 Sequence프로토콜 따르는 물체 ( Dictionary, Set등)이라는 두 가지 방법이 있습니다 max()max(by:)순서를 돌려 최대 요소 또는 nil시퀀스는 비어있는 경우.


#1. 사용 Arraymax()방법을

시퀀스 내부의 요소 유형이 Comparable프로토콜을 준수 하는 경우 (String , Float, Character또는 사용자 정의 클래스 또는 구조체 중 하나), 당신은 사용할 수있을 것이다 max()그 다음이 선언 :

@warn_unqualified_access func max() -> Element?

시퀀스의 최대 요소를 반환합니다.

다음 플레이 그라운드 코드는 사용 방법을 보여줍니다 max().

let intMax = [12, 15, 6].max()
let stringMax = ["bike", "car", "boat"].max()

print(String(describing: intMax)) // prints: Optional(15)
print(String(describing: stringMax)) // prints: Optional("car")
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 routes = [
    Route(distance: 20),
    Route(distance: 30),
    Route(distance: 10)
]

let maxRoute = routes.max()
print(String(describing: maxRoute)) // prints: Optional(Route with distance: 30)

# 2. 사용 Array의를max(by:) 방법을

시퀀스 내부의 요소 유형이 Comparable프로토콜을 준수하지 않는 경우 다음을 사용해야합니다.max(by:) 경우 다음 선언 이있는 합니다 .

@warn_unqualified_access func max(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element?

주어진 술어를 요소 간의 비교로 사용하여 시퀀스의 최대 요소를 리턴합니다.

다음 플레이 그라운드 코드는 사용 방법을 보여줍니다 max(by:).

let dictionary = ["Boat" : 15, "Car" : 20, "Bike" : 40]

let keyMaxElement = dictionary.max(by: { (a, b) -> Bool in
    return a.key < b.key
})

let valueMaxElement = dictionary.max(by: { (a, b) -> Bool in
    return a.value < b.value
})

print(String(describing: keyMaxElement)) // prints: Optional(("Car", 20))
print(String(describing: valueMaxElement)) // prints: Optional(("Bike", 40))
class Route: CustomStringConvertible {

    let distance: Int
    var description: String { return "Route with distance: \(distance)" }

    init(distance: Int) {
        self.distance = distance
    }

}

let routes = [
    Route(distance: 20),
    Route(distance: 30),
    Route(distance: 10)
]

let maxRoute = routes.max(by: { (a, b) -> Bool in
    return a.distance < b.distance
})

print(String(describing: maxRoute)) // prints: Optional(Route with distance: 30)

스위프트 3에서 "maxElement"는 "최대"로 이름이 바뀌 었습니다
니콜라이 헨릭슨을

16

다른 답변은 모두 정확하지만 다음과 같이 컬렉션 연산자를 사용할 수도 있다는 것을 잊지 마십시오.

var list = [1, 2, 3, 4]
var max: Int = (list as AnyObject).valueForKeyPath("@max.self") as Int

같은 방법으로 평균을 찾을 수도 있습니다.

var avg: Double = (list as AnyObject).valueForKeyPath("@avg.self") as Double

이 구문은 다른 솔루션보다 명확하지 않을 수 있지만 -valueForKeyPath:여전히 사용할 수 있다는 점 은 흥미 롭습니다. :)


11

다음과 함께 사용할 수 있습니다 reduce.

let randomNumbers = [4, 7, 1, 9, 6, 5, 6, 9]
let maxNumber = randomNumbers.reduce(randomNumbers[0]) { $0 > $1 ? $0 : $1 } //result is 9

4
var numbers = [1, 2, 7, 5];    
var val = sort(numbers){$0 > $1}[0];

2
나에게 이것은 매우 비슷합니다var myMax = sort(myArray,>)[0]
Charlie Egan

3
정렬에 너무 많은 오버 헤드가 있습니다.
vy32

4

Swift 1.2 (또는 이전 버전)에서는 이제 다음을 사용해야합니다.

let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, combine: { max($0, $1) })

Double 값으로 작업하기 위해 다음과 같이 사용했습니다.

let nums = [1.3, 6.2, 3.6, 9.7, 4.9, 6.3];
let numMax = nums.reduce(-Double.infinity, combine: { max($0, $1) })

1
이렇게 할 수도 있습니다 let numMax = nums.reduce(-Double.infinity, combine: max). max 함수 서명은 combine : 매개 변수 서명과 일치합니다.
Leslie Godwin

3

Swift 2.0에서는 프로토콜의 메소드가되고 다음 minElement과 같이 호출해야합니다.maxElementSequenceType

let a = [1, 2, 3]
print(a.maxElement()) //3
print(a.minElement()) //1

사용 maxElement하는 기능으로 같은 maxElement(a)것입니다 사용할 수 없습니다 지금.

Swift의 구문은 유동적이므로 Xcode version7 beta6 에서 확인할 수 있습니다 .

향후 수정 될 수 있으므로 이러한 방법을 사용하기 전에 문서를 확인하는 것이 좋습니다.


3

스위프트 3.0

이 코드를 프로그래밍 방식으로 시도 할 수 있습니다.

func getSmallAndGreatestNumber() -> Void {

    let numbers = [145, 206, 116, 809, 540, 176]
    var i = 0
    var largest = numbers[0]
    var small = numbers[0]
    while i < numbers.count{

        if (numbers[i] > largest) {
            largest = numbers[i]
        }
        if (numbers[i] < small) {
            small = numbers[i]
        }
        i = i + 1
    }
    print("Maximum Number ====================\(largest)")// 809
    print("Minimum Number ====================\(small)")// 116
}


0

Swift 3/4 업데이트 :

아래의 간단한 코드 줄을 사용하여 배열에서 최대 값을 찾으십시오.

var num = [11, 2, 7, 5, 21]
var result = num.sorted(){
    $0 > $1
}
print("max from result: \(result[0])") // 21

-1

배열을 정렬 한 다음 array.first또는array.last


5
이것은 계산적으로 더 느립니다. 선형 시간에서 최대 값을 찾을 수 있습니다.
Charlie Egan

저는 매우 새로운 @CharlieEgan입니다. 선형 시간을 설명하거나 튜토리얼을 알려 주시겠습니까? 고마워요
사드 Ghadir

'시간 복잡성'( en.wikipedia.org/wiki/Time_complexity )에 대해 읽어보십시오 . 이것은 또한 읽을 가치가 있습니다 : bigocheatsheet.com . 좋은 여기에 예를 일 : khanacademy.org/computing/computer-science/algorithms
찰리 이건
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.