You can extend Sequence and implement custom max and min methods to allow you to specify a keypath of a property that conform to Comparable:
extension Sequence {
func max<T: Comparable>(_ predicate: (Element) -> T) -> Element? {
self.max(by: { predicate($0) < predicate($1) })
}
func min<T: Comparable>(_ predicate: (Element) -> T) -> Element? {
self.min(by: { predicate($0) < predicate($1) })
}
}
let points: [CGPoint] = [.init(x: 1.2, y: 3.4),
.init(x: 0.1, y: 2.2),
.init(x: 2.3, y: 1.1)]
let maxX = points.max(\.x)
let maxY = points.max(\.y)
print("maxX:", maxX ?? "nil")
print("maxY:", maxY ?? "nil")
let minX = points.min(\.x)
let minY = points.min(\.y)
print("minX:", minX ?? "nil")
print("minY:", minY ?? "nil")
This will print
maxX: (2.3, 1.1)
maxY: (1.2, 3.4)
minX: (0.1, 2.2)
minY: (2.3, 1.1)