可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've so far got a simple (but potentially expensive) way:
var myMax = sort(myArray,>)[0]
And how I was taught to do it at school:
var myMax = 0
for i in 0..myArray.count {
if (myArray[i] > myMax){myMax = myArray[i]}
}
Is there a better way to get the maximum value from an integer Array in Swift? Ideally something that's one line such as Ruby's .max
回答1:
Given:
let numbers = [1, 2, 3, 4, 5]
Swift 3:
numbers.min() // equals 1
numbers.max() // equals 5
Swift 2:
numbers.minElement() // equals 1
numbers.maxElement() // equals 5
回答2:
Update: This should probably be the accepted answer since maxElement
appeared in Swift.
Use the almighty reduce
:
let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, { max($0, $1) })
Similarly:
let numMin = nums.reduce(Int.max, { min($0, $1) })
reduce
takes a first value that is the initial value for an internal accumulator variable, then applies the passed function (here, it's anonymous) to the accumulator and each element of the array successively, and stores the new value in the accumulator. The last accumulator value is then returned.
回答3:
With Swift 5, Array
, like other Sequence
Protocol conforming objects (Dictionary
, Set
, etc), has two methods called max()
and max(by:)
that return the maximum element in the sequence or nil
if the sequence is empty.
#1. Using Array
's max()
method
If the element type inside your sequence conforms to Comparable
protocol (may it be String
, Float
, Character
or one of your custom class or struct), you will be able to use max()
that has the following declaration:
@warn_unqualified_access func max() -> Element?
Returns the maximum element in the sequence.
The following Playground codes show to use 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. Using Array
's max(by:)
method
If the element type inside your sequence does not conform to Comparable
protocol, you will have to use max(by:)
that has the following declaration:
@warn_unqualified_access func max(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element?
Returns the maximum element in the sequence, using the given predicate as the comparison between elements.
The following Playground codes show to use 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)
回答4:
The other answers are all correct, but don't forget you could also use collection operators, as follows:
var list = [1, 2, 3, 4]
var max: Int = (list as AnyObject).valueForKeyPath("@max.self") as Int
you can also find the average in the same way:
var avg: Double = (list as AnyObject).valueForKeyPath("@avg.self") as Double
This syntax might be less clear than some of the other solutions, but it's interesting to see that -valueForKeyPath:
can still be used :)
回答5:
You can use with reduce
:
let randomNumbers = [4, 7, 1, 9, 6, 5, 6, 9]
let maxNumber = randomNumbers.reduce(randomNumbers[0]) { $0 > $1 ? $0 : $1 } //result is 9
回答6:
var numbers = [1, 2, 7, 5];
var val = sort(numbers){$0 > $1}[0];
回答7:
With Swift 1.2 (and maybe earlier) you now need to use:
let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, combine: { max($0, $1) })
For working with Double values I used something like this:
let nums = [1.3, 6.2, 3.6, 9.7, 4.9, 6.3];
let numMax = nums.reduce(-Double.infinity, combine: { max($0, $1) })
回答8:
In Swift 2.0, the minElement
and maxElement
become methods of SequenceType
protocol, you should call them like:
let a = [1, 2, 3]
print(a.maxElement()) //3
print(a.minElement()) //1
Using maxElement
as a function like maxElement(a)
is unavailable now.
The syntax of Swift is in flux, so I can just confirm this in Xcode version7 beta6.
It may be modified in the future, so I suggest that you'd better check the doc before you use these methods.
回答9:
Swift 3.0
You can try this code programmatically.
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
}
回答10:
Updated for Swift 3/4:
Use below simple lines of code to find the max from array;
var num = [11, 2, 7, 5, 21]
var result = num.sorted(){
$0 > $1
}
print("max from result: \(result[0])") // 21
回答11:
Here's a performance test for the solutions posted here. https://github.com/tedgonzalez/MaxElementInCollectionPerformance
This is the fastest for Swift 5
array.max()
回答12:
You can also sort your array and then use array.first
or array.last