]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmp: add Or
authorCarl Johnson <me@carlmjohnson.net>
Fri, 22 Sep 2023 21:03:27 +0000 (21:03 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 25 Sep 2023 14:30:20 +0000 (14:30 +0000)
Fixes #60204

Change-Id: I1234cacf0f25097d034038bcfb33f6630373a057
GitHub-Last-Rev: e9098ed8b3dd9125661e4340ffe01d846670ba0f
GitHub-Pull-Request: golang/go#60931
Reviewed-on: https://go-review.googlesource.com/c/go/+/504883
Auto-Submit: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: qiulaidongfeng <2645477756@qq.com>
api/next/60204.txt [new file with mode: 0644]
src/cmp/cmp.go
src/cmp/cmp_test.go

diff --git a/api/next/60204.txt b/api/next/60204.txt
new file mode 100644 (file)
index 0000000..62dddc6
--- /dev/null
@@ -0,0 +1 @@
+pkg cmp, func Or[$0 comparable](...$0) $0 #60204
index 0fba5c121162237c080c8aeb1b387fa8142f5330..4d1af6a98c4e46ee3f839196bf7a463d0cc6ce48 100644 (file)
@@ -57,3 +57,15 @@ func Compare[T Ordered](x, y T) int {
 func isNaN[T Ordered](x T) bool {
        return x != x
 }
+
+// Or returns the first of its arguments that is not equal to the zero value.
+// If no argument is non-zero, it returns the zero value.
+func Or[T comparable](vals ...T) T {
+       var zero T
+       for _, val := range vals {
+               if val != zero {
+                       return val
+               }
+       }
+       return zero
+}
index b0c0dc3fbde9824382dd67121f83d40da1d2dc7f..0bb39c69410d82e6d381137e44b693e168e69473 100644 (file)
@@ -6,8 +6,10 @@ package cmp_test
 
 import (
        "cmp"
+       "fmt"
        "math"
        "sort"
+       "slices"
        "testing"
 )
 
@@ -93,3 +95,73 @@ func TestSort(t *testing.T) {
                }
        }
 }
+
+func TestOr(t *testing.T) {
+       cases := []struct {
+               in   []int
+               want int
+       }{
+               {nil, 0},
+               {[]int{0}, 0},
+               {[]int{1}, 1},
+               {[]int{0, 2}, 2},
+               {[]int{3, 0}, 3},
+               {[]int{4, 5}, 4},
+               {[]int{0, 6, 7}, 6},
+       }
+       for _, tc := range cases {
+               if got := cmp.Or(tc.in...); got != tc.want {
+                       t.Errorf("cmp.Or(%v) = %v; want %v", tc.in, got, tc.want)
+               }
+       }
+}
+
+func ExampleOr() {
+       // Suppose we have some user input
+       // that may or may not be an empty string
+       userInput1 := ""
+       userInput2 := "some text"
+
+       fmt.Println(cmp.Or(userInput1, "default"))
+       fmt.Println(cmp.Or(userInput2, "default"))
+       fmt.Println(cmp.Or(userInput1, userInput2, "default"))
+       // Output:
+       // default
+       // some text
+       // some text
+}
+
+func ExampleOr_sort() {
+       type Order struct {
+               Product string
+               Customer string
+               Price float64
+       }
+       orders := []Order{
+               {"foo", "alice", 1.00},
+               {"bar", "bob", 3.00},
+               {"baz", "carol", 4.00},
+               {"foo", "alice", 2.00},
+               {"bar", "carol", 1.00},
+               {"foo", "bob", 4.00},
+       }
+       // Sort by customer first, product second, and last by higher price
+       slices.SortFunc(orders, func(a, b Order) int {
+               return cmp.Or(
+                       cmp.Compare(a.Customer, b.Customer),
+                       cmp.Compare(a.Product, b.Product),
+                       cmp.Compare(b.Price, a.Price),
+               )
+       })
+       for _, order := range orders {
+               fmt.Printf("%s %s %.2f\n", order.Product, order.Customer, order.Price)
+       }
+
+       // Output:
+       // foo alice 2.00
+       // foo alice 1.00
+       // bar bob 3.00
+       // foo bob 4.00
+       // bar carol 1.00
+       // baz carol 4.00
+}