Skip to content

Commit 12a2f0d

Browse files
committed
Add keyPath versions of Array.{min,max,minmax}
1 parent 2e3028b commit 12a2f0d

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

Sources/Extensions/Array/Array+Reducers.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ public extension Array {
5252

5353
public extension Array where Element: Comparable {
5454

55+
/// Finds the minimum element in the array.
56+
func min<T: Comparable>(byValue value: KeyPath<Element, T>) -> Element? {
57+
self.min(by: {
58+
$0[keyPath: value] < $1[keyPath: value]
59+
})
60+
}
61+
62+
/// Finds the maximum element in the array.
63+
func max<T: Comparable>(byValue value: KeyPath<Element, T>) -> Element? {
64+
self.max(by: {
65+
$0[keyPath: value] < $1[keyPath: value]
66+
})
67+
}
68+
5569
/// Finds the minimum and maximum elements in the array.
5670
///
5771
/// This method traverses the array to find the smallest and largest elements. If the array is empty,
@@ -72,6 +86,29 @@ public extension Array where Element: Comparable {
7286

7387
return (min, max)
7488
}
89+
90+
/// Finds the minimum and maximum elements in the array.
91+
///
92+
/// This method traverses the array to find the smallest and largest elements. If the array is empty,
93+
/// it returns `nil`. Otherwise, it returns a tuple containing the minimum and maximum elements.
94+
///
95+
/// - Parameter value: A key path that specifies the property to compare.
96+
/// - Returns: An optional tuple representing the minimum and maximum elements in the array, or `nil`
97+
/// if the array is empty.
98+
func minmax<T: Comparable>(byValue value: KeyPath<Element, T>) -> (min: T, max: T)? {
99+
guard let firstElement = self.first else { return nil }
100+
101+
var min: T = firstElement[keyPath: value]
102+
var max: T = firstElement[keyPath: value]
103+
104+
for e in self.dropFirst() {
105+
let value = e[keyPath: value]
106+
if value < min { min = value }
107+
if value > max { max = value }
108+
}
109+
110+
return (min, max)
111+
}
75112
}
76113

77114
public extension Array where Element: Comparable & SignedNumeric {

Tests/Extensions/ArrayTests.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,23 @@ final class ArrayTests: XCTestCase {
1717
XCTAssertTrue(subject.noneSatisfy { $0 % 2 == 0 })
1818
XCTAssertFalse(subject.noneSatisfy { $0 >= 0 })
1919
}
20-
20+
21+
func testMin() {
22+
let subject = [-3, -5, 0, 4, 7]
23+
24+
let result = subject.min(byValue: \.self)
25+
26+
XCTAssertEqual(result, -5)
27+
}
28+
29+
func testMax() {
30+
let subject = [-5, -3, 7, 4, 0]
31+
32+
let result = subject.max(byValue: \.self)
33+
34+
XCTAssertEqual(result, 7)
35+
}
36+
2137
func testMinMax() {
2238
let subject = [-5, -3, 0, 4, 7]
2339

0 commit comments

Comments
 (0)