在Swift中找到数组中max的正确方法

时间:2014-06-04 11:45:06

标签: arrays swift

到目前为止,我有一种简单(但可能很昂贵)的方式:

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

我是如何被教导在学校做的:

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

有没有更好的方法从Swift中的整数数组中获取最大值?理想情况下,像Ruby的.max

这样的一行

13 个答案:

答案 0 :(得分:262)

假设:

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

答案 1 :(得分:90)

更新: This应该是自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取第一个值作为内部累加器变量的初始值,然后将传递的函数(这里,它是匿名的)连续地应用于累加器和数组的每个元素,并且将新值存储在累加器中。然后返回最后一个累加器值。

答案 2 :(得分:33)

使用Swift 5,Array与其他Sequence符合协议的对象(DictionarySet等)一样,有两种方法max()和{ {1}}返回序列中的最大元素,如果序列为空则返回max(by:)

#1。使用nil' Array方法

如果序列中的元素类型符合max()协议(可能是ComparableStringFloat或您的某个自定义类或结构,那么将能够使用具有以下declarationCharacter

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")

#2。使用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) &#39; Array方法

如果序列中的元素类型不符合max(by:)协议,则必须使用具有以下declarationComparable

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))

答案 3 :(得分:14)

其他答案都是正确的,但不要忘记你也可以使用集合运算符,如下所示:

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:很有意思:)

答案 4 :(得分:8)

您可以使用reduce

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

答案 5 :(得分:2)

使用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) })

答案 6 :(得分:1)

在Swift 2.0中,minElementmaxElement成为SequenceType协议的方法,您应该将它们称为:

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

现在将maxElement用作 maxElement(a) 等功能不可用

Swift的语法不断变化,所以我可以在 Xcode version7 beta6 中确认这一点。

将来可能会进行修改,因此我建议您在使用这些方法之前更好地检查文档。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

Swift 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
}

答案 9 :(得分:0)

  

更新了Swift 3/4:

使用下面的简单代码行从数组中找到最大值;

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

答案 10 :(得分:0)

这是此处发布的解决方案的性能测试。 https://github.com/tedgonzalez/MaxElementInCollectionPerformance

这是 Swift 5

最快的

array.max()

答案 11 :(得分:0)

只是好奇为什么您认为在学校教授的方式可能很昂贵?您正在运行一个时间复杂度为 O(N) 的 for 循环。这实际上比大多数排序算法都要好,相当于 reduce 等高阶方法的性能。

所以我认为就性能而言,for 循环已经足够好了。我不认为你会找到比 O(N) 更好的方法来寻找最大值。

当然,只要使用apple提供的.max()方法就行了。

答案 12 :(得分:-2)

您还可以对数组进行排序,然后使用_array.first