Hoe kan ik de minimum- en maximumwaarden vinden aan de hand van een reeks Swift-numerieke waarden?
Ik heb tot nu toe een eenvoudige (maar potentieel dure) manier:
var myMax = sort(myArray,>)[0]
En hoe ik het op school heb geleerd:
var myMax = 0
for i in 0..myArray.count {
if (myArray[i] > myMax){myMax = myArray[i]}
}
Is er een betere manier om de minimum- of maximumwaarde uit een integer-array in Swift te halen? Idealiter is dat één regel, zoals Ruby’s .min
en .max
.
Antwoord 1, autoriteit 100%
Gegeven:
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
Antwoord 2, autoriteit 31%
Om de min en max waarden van een array zelf te berekenen, kun je reduce
gebruiken. Dit was een belangrijke oplossing voordat .min()
en .max()
in Swift verschenen.
Gebruik de almachtige reduce
:
let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, { max($0, $1) })
Ook:
let numMin = nums.reduce(Int.max, { min($0, $1) })
reduce
neemt een eerste waarde die de initiële waarde is voor een interne accumulatorvariabele, past vervolgens de doorgegeven functie (hier is het anoniem) toe op de accumulator en elk element van de array achtereenvolgens, en slaat op de nieuwe waarde in de accumulator. De laatste accumulatorwaarde wordt dan geretourneerd.
Antwoord 3, autoriteit 14%
Met Swift 5, Array
, zoals andere Sequence
Protocol-conforme objecten (Dictionary
, Set
, enz.) , heeft twee methoden genaamd max()
en max(by:)
die het maximum element in de reeks retourneren of nil
als de reeks leeg is .
#1. Met behulp van Array
‘s max()
methode
Als het elementtype in uw reeks voldoet aan het Comparable
-protocol (mag het String
, Float
, Character
of een van uw aangepaste klassen of struct), kunt u max()
gebruiken met de volgende verklaring:
@warn_unqualified_access func max() -> Element?
Retourneert het maximum element in de reeks.
De volgende Playground-codes geven aan dat je max()
moet gebruiken:
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. Met behulp van Array
‘s max(by:)
methode
Als het elementtype in uw reeks niet voldoet aan het Comparable
-protocol, moet u max(by:)
gebruiken met de volgende verklaring:
@warn_unqualified_access func max(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element?
Retourneert het maximale element in de reeks, waarbij het gegeven predikaat wordt gebruikt als vergelijking tussen elementen.
De volgende Playground-codes geven aan dat je max(by:)
moet gebruiken:
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)
Antwoord 4, autoriteit 5%
De andere antwoorden zijn allemaal correct, maar vergeet niet dat u ook verzamelingsoperatoren kunt gebruiken, als volgt:
var list = [1, 2, 3, 4]
var max: Int = (list as AnyObject).valueForKeyPath("@max.self") as Int
je kunt het gemiddelde ook op dezelfde manier vinden:
var avg: Double = (list as AnyObject).valueForKeyPath("@avg.self") as Double
Deze syntaxis is misschien minder duidelijk dan sommige van de andere oplossingen, maar het is interessant om te zien dat -valueForKeyPath:
nog steeds kan worden gebruikt 🙂
Antwoord 5, autoriteit 3%
U kunt gebruiken met reduce
:
let randomNumbers = [4, 7, 1, 9, 6, 5, 6, 9]
let maxNumber = randomNumbers.reduce(randomNumbers[0]) { $0 > $1 ? $0 : $1 } //result is 9
Antwoord 6, autoriteit 2%
Swift 3.0
Je kunt deze code programmatisch proberen.
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
}
Antwoord 7
Met Swift 1.2 (en misschien eerder) moet je nu het volgende gebruiken:
let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, combine: { max($0, $1) })
Voor het werken met dubbele waarden heb ik zoiets als dit gebruikt:
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
U kunt uw array ook sorteren en vervolgens array.first
of array.last
gebruiken