Ответ 1
Дано:
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
Я до сих пор получил простой (но потенциально дорого) способ:
var myMax = sort(myArray,>)[0]
И как меня учили делать это в школе:
var myMax = 0
for i in 0..myArray.count {
if (myArray[i] > myMax){myMax = myArray[i]}
}
Есть ли лучший способ получить максимальное значение из целочисленного массива в Swift? В идеале что-то, что одна строка, такая как Ruby .max
Дано:
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
Обновление: Это, вероятно, должно быть принятым ответом, поскольку 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
принимает первое значение, которое является начальным значением для внутренней переменной накопителя, затем последовательно применяет переданную функцию (здесь, она анонимно) к аккумулятору и каждому элементу массива и сохраняет новое значение в аккумулятор. Затем возвращается последнее значение аккумулятора.
В Swift 5 Array
, как и другие объекты, соответствующие протоколу Sequence
(Dictionary
, Set
и т.д.), Имеет два метода: max()
и max(by:)
которые возвращают максимальный элемент в последовательности или nil
если последовательность пуста.
Array
max()
Если тип элемента в вашей последовательности соответствует протоколу 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)
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)
Другие ответы правильны, но не забывайте, что вы также можете использовать операторы коллекции следующим образом:
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:
все еще можно использовать:)
Вы можете использовать с reduce
:
let randomNumbers = [4, 7, 1, 9, 6, 5, 6, 9]
let maxNumber = randomNumbers.reduce(randomNumbers[0]) { $0 > $1 ? $0 : $1 } //result is 9
С Swift 1.2 (и, возможно, раньше) вам теперь нужно использовать:
let nums = [1, 6, 3, 9, 4, 6];
let numMax = nums.reduce(Int.min, combine: { max($0, $1) })
Для работы с двойными значениями я использовал что-то вроде этого:
let nums = [1.3, 6.2, 3.6, 9.7, 4.9, 6.3];
let numMax = nums.reduce(-Double.infinity, combine: { max($0, $1) })
var numbers = [1, 2, 7, 5];
var val = sort(numbers){$0 > $1}[0];
В Swift 2.0 методы minElement
и maxElement
становятся методами протокола SequenceType
, вы должны называть их такими:
let a = [1, 2, 3]
print(a.maxElement()) //3
print(a.minElement()) //1
Использование maxElement
как функции maxElement(a)
теперь недоступно.
Синтаксис Swift в потоке, поэтому я могу просто подтвердить это в Xcode version7 beta6.
Он может быть изменен в будущем, поэтому я предлагаю вам лучше проверить документ перед использованием этих методов.
Обновлено для Swift 3/4:
Используйте ниже простые строки кода, чтобы найти максимум из массива;
var num = [11, 2, 7, 5, 21]
var result = num.sorted(){
$0 > $1
}
print("max from result: \(result[0])") // 21
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
}
Здесь тест производительности для решений размещен здесь. https://github.com/tedgonzalez/MaxElementInCollectionPerformance
Это самый быстрый для Swift 5
array.max()
Вы также можете отсортировать свой массив, а затем использовать array.first
или array.last