Skip to content

Commit

Permalink
slices: clarify MinFunc/MaxFunc result for equal elements
Browse files Browse the repository at this point in the history
They should return the first of equal elements. No such clarification
is required for Min/Max as for them equal elements are indistinguishable.

For golang#60091

Change-Id: Iad58115d482add852c811e993131702b5b3bec5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/505796
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Eli Bendersky <eliben@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
  • Loading branch information
ianlancetaylor authored and bradfitz committed Jul 15, 2023
1 parent 1d69b64 commit 5821240
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/slices/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ func Min[S ~[]E, E cmp.Ordered](x S) E {
}

// MinFunc returns the minimal value in x, using cmp to compare elements.
// It panics if x is empty.
// It panics if x is empty. If there is more than one minimal element
// according to the cmp function, MinFunc returns the first one.
func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
if len(x) < 1 {
panic("slices.MinFunc: empty list")
Expand Down Expand Up @@ -99,7 +100,8 @@ func Max[S ~[]E, E cmp.Ordered](x S) E {
}

// MaxFunc returns the maximal value in x, using cmp to compare elements.
// It panics if x is empty.
// It panics if x is empty. If there is more than one maximal element
// according to the cmp function, MaxFunc returns the first one.
func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
if len(x) < 1 {
panic("slices.MaxFunc: empty list")
Expand Down
28 changes: 28 additions & 0 deletions src/slices/sort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ func TestStability(t *testing.T) {
}
}

type S struct {
a int
b string
}

func cmpS(s1, s2 S) int {
return cmp.Compare(s1.a, s2.a)
}

func TestMinMax(t *testing.T) {
intCmp := func(a, b int) int { return a - b }

Expand Down Expand Up @@ -214,6 +223,25 @@ func TestMinMax(t *testing.T) {
}
})
}

svals := []S{
{1, "a"},
{2, "a"},
{1, "b"},
{2, "b"},
}

gotMin := MinFunc(svals, cmpS)
wantMin := S{1, "a"}
if gotMin != wantMin {
t.Errorf("MinFunc(%v) = %v, want %v", svals, gotMin, wantMin)
}

gotMax := MaxFunc(svals, cmpS)
wantMax := S{2, "a"}
if gotMax != wantMax {
t.Errorf("MaxFunc(%v) = %v, want %v", svals, gotMax, wantMax)
}
}

func TestMinMaxNaNs(t *testing.T) {
Expand Down

0 comments on commit 5821240

Please sign in to comment.