Skip to content

Commit 61e2b30

Browse files
committed
Merge pull request #615 from PatrickPijnappel/min-max
[stdlib] Refactor min()/max()
2 parents 18938ac + a61839d commit 61e2b30

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

stdlib/public/core/Algorithm.swift

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,47 +44,50 @@ public func find<
4444
}
4545

4646
/// Returns the lesser of `x` and `y`.
47+
///
48+
/// If `x == y`, returns `x`.
4749
@warn_unused_result
4850
public func min<T : Comparable>(x: T, _ y: T) -> T {
49-
var r = x
50-
if y < x {
51-
r = y
52-
}
53-
return r
51+
// In case `x == y` we pick `x`.
52+
// This preserves any pre-existing order in case `T` has identity,
53+
// which is important for e.g. the stability of sorting algorithms.
54+
// `(min(x, y), max(x, y))` should return `(x, y)` in case `x == y`.
55+
return y < x ? y : x
5456
}
5557

5658
/// Returns the least argument passed.
59+
///
60+
/// If there are multiple equal least arguments, returns the first one.
5761
@warn_unused_result
5862
public func min<T : Comparable>(x: T, _ y: T, _ z: T, _ rest: T...) -> T {
59-
var r = x
60-
if y < x {
61-
r = y
62-
}
63-
if z < r {
64-
r = z
63+
var minValue = min(min(x, y), z)
64+
// In case `value == minValue`, we pick `minValue`. See min(_:_:).
65+
for value in rest where value < minValue {
66+
minValue = value
6567
}
66-
for t in rest {
67-
if t < r {
68-
r = t
69-
}
70-
}
71-
return r
68+
return minValue
7269
}
7370

7471
/// Returns the greater of `x` and `y`.
72+
///
73+
/// If `x == y`, returns `y`.
7574
@warn_unused_result
7675
public func max<T : Comparable>(x: T, _ y: T) -> T {
76+
// In case `x == y`, we pick `y`. See min(_:_:).
7777
return y >= x ? y : x
7878
}
7979

8080
/// Returns the greatest argument passed.
81+
///
82+
/// If there are multiple equal greatest arguments, returns the last one.
8183
@warn_unused_result
8284
public func max<T : Comparable>(x: T, _ y: T, _ z: T, _ rest: T...) -> T {
83-
var r = max(max(x, y), z)
84-
for t in rest where t >= r {
85-
r = t
85+
var maxValue = max(max(x, y), z)
86+
// In case `value == maxValue`, we pick `value`. See min(_:_:).
87+
for value in rest where value >= maxValue {
88+
maxValue = value
8689
}
87-
return r
90+
return maxValue
8891
}
8992

9093
/// Returns the result of slicing `elements` into sub-sequences that

0 commit comments

Comments
 (0)