From 2166e61181f712d4a7c8a29b019fe7d122ffc8a3 Mon Sep 17 00:00:00 2001
From: Eli Bendersky
Date: Mon, 21 Aug 2023 12:47:17 -0700
Subject: [PATCH] Update sorting-by-functions example to use slices.SortFunc
---
.../sorting-by-functions.go | 66 +++++-----
.../sorting-by-functions.hash | 4 +-
.../sorting-by-functions.sh | 9 +-
public/sorting-by-functions | 122 ++++++++++--------
4 files changed, 109 insertions(+), 92 deletions(-)
diff --git a/examples/sorting-by-functions/sorting-by-functions.go b/examples/sorting-by-functions/sorting-by-functions.go
index 8524f66..d54d79e 100644
--- a/examples/sorting-by-functions/sorting-by-functions.go
+++ b/examples/sorting-by-functions/sorting-by-functions.go
@@ -7,39 +7,47 @@
package main
import (
+ "cmp"
"fmt"
- "sort"
+ "slices"
)
-// In order to sort by a custom function in Go, we need a
-// corresponding type. Here we've created a `byLength`
-// type that is just an alias for the builtin `[]string`
-// type.
-type byLength []string
-
-// We implement `sort.Interface` - `Len`, `Less`, and
-// `Swap` - on our type so we can use the `sort` package's
-// generic `Sort` function. `Len` and `Swap`
-// will usually be similar across types and `Less` will
-// hold the actual custom sorting logic. In our case we
-// want to sort in order of increasing string length, so
-// we use `len(s[i])` and `len(s[j])` here.
-func (s byLength) Len() int {
- return len(s)
-}
-func (s byLength) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-func (s byLength) Less(i, j int) bool {
- return len(s[i]) < len(s[j])
-}
-
-// With all of this in place, we can now implement our
-// custom sort by converting the original `fruits` slice
-// to `byLength`, and then use `sort.Sort` on that typed
-// slice.
func main() {
fruits := []string{"peach", "banana", "kiwi"}
- sort.Sort(byLength(fruits))
+
+ // We implement a comparison function for string
+ // lengths. `cmp.Compare` is helpful for this.
+ lenCmp := func(a, b string) int {
+ return cmp.Compare(len(a), len(b))
+ }
+
+ // Now we can call `slices.SortFunc` with this custom
+ // comparison function to sort `fruits` by name length.
+ slices.SortFunc(fruits, lenCmp)
fmt.Println(fruits)
+
+ // We can use the same technique to sort a slice of
+ // values that aren't built-in types.
+ type Person struct {
+ name string
+ age int
+ }
+
+ people := []Person{
+ Person{name: "Jax", age: 37},
+ Person{name: "TJ", age: 25},
+ Person{name: "Alex", age: 72},
+ }
+
+ // Sort `people` by age using `slices.SortFunc`.
+ //
+ // Note: if the `Person` struct is large,
+ // you may want the slice to contain `*Person` instead
+ // and adjust the sorting function accordingly. If in
+ // doubt, [benchmark](testing-and-benchmarking)!
+ slices.SortFunc(people,
+ func(a, b Person) int {
+ return cmp.Compare(a.age, b.age)
+ })
+ fmt.Println(people)
}
diff --git a/examples/sorting-by-functions/sorting-by-functions.hash b/examples/sorting-by-functions/sorting-by-functions.hash
index ff61f81..8413a10 100644
--- a/examples/sorting-by-functions/sorting-by-functions.hash
+++ b/examples/sorting-by-functions/sorting-by-functions.hash
@@ -1,2 +1,2 @@
-e5a6006366e05ee7785eebac8ba588e4b937a197
-h4g4vaLBtkw
+9902d1c5654b64d8b381ea7888c0793ac8ab4a97
+3EaTknAZHMu
diff --git a/examples/sorting-by-functions/sorting-by-functions.sh b/examples/sorting-by-functions/sorting-by-functions.sh
index d2a1c4c..eb8b9b4 100644
--- a/examples/sorting-by-functions/sorting-by-functions.sh
+++ b/examples/sorting-by-functions/sorting-by-functions.sh
@@ -1,10 +1,3 @@
-# Running our program shows a list sorted by string
-# length, as desired.
$ go run sorting-by-functions.go
[kiwi peach banana]
-
-# By following this same pattern of creating a custom
-# type, implementing the three `Interface` methods on that
-# type, and then calling sort.Sort on a collection of that
-# custom type, we can sort Go slices by arbitrary
-# functions.
+[{TJ 25} {Jax 37} {Alex 72}]
diff --git a/public/sorting-by-functions b/public/sorting-by-functions
index 77b833c..43e5f47 100644
--- a/public/sorting-by-functions
+++ b/public/sorting-by-functions
@@ -45,7 +45,7 @@ in Go.
- 
+ 
package main
|
@@ -57,65 +57,97 @@ in Go.
import (
+ "cmp"
"fmt"
- "sort"
+ "slices"
)
|
- In order to sort by a custom function in Go, we need a
-corresponding type. Here we’ve created a byLength
-type that is just an alias for the builtin []string
-type.
-
+
|
- type byLength []string
+ func main() {
+ fruits := []string{"peach", "banana", "kiwi"}
|
- We implement sort.Interface - Len , Less , and
-Swap - on our type so we can use the sort package’s
-generic Sort function. Len and Swap
-will usually be similar across types and Less will
-hold the actual custom sorting logic. In our case we
-want to sort in order of increasing string length, so
-we use len(s[i]) and len(s[j]) here.
+ We implement a comparison function for string
+lengths. cmp.Compare is helpful for this.
|
- func (s byLength) Len() int {
- return len(s)
-}
-func (s byLength) Swap(i, j int) {
- s[i], s[j] = s[j], s[i]
-}
-func (s byLength) Less(i, j int) bool {
- return len(s[i]) < len(s[j])
-}
+ lenCmp := func(a, b string) int {
+ return cmp.Compare(len(a), len(b))
+ }
|
- With all of this in place, we can now implement our
-custom sort by converting the original fruits slice
-to byLength , and then use sort.Sort on that typed
-slice.
+ Now we can call slices.SortFunc with this custom
+comparison function to sort fruits by name length.
+
+ |
+
+
+ slices.SortFunc(fruits, lenCmp)
+ fmt.Println(fruits)
+ |
+
+
+
+
+ We can use the same technique to sort a slice of
+values that aren’t built-in types.
+
+ |
+
+
+ type Person struct {
+ name string
+ age int
+ }
+ |
+
+
+
+
+
+ |
+
+
+ people := []Person{
+ Person{name: "Jax", age: 37},
+ Person{name: "TJ", age: 25},
+ Person{name: "Alex", age: 72},
+ }
+ |
+
+
+
+
+ Sort people by age using slices.SortFunc .
+
+Note: if the Person struct is large,
+you may want the slice to contain *Person instead
+and adjust the sorting function accordingly. If in
+doubt, benchmark!
|
- func main() {
- fruits := []string{"peach", "banana", "kiwi"}
- sort.Sort(byLength(fruits))
- fmt.Println(fruits)
+ slices.SortFunc(people,
+ func(a, b Person) int {
+ return cmp.Compare(a.age, b.age)
+ })
+ fmt.Println(people)
}
|
@@ -126,29 +158,13 @@ slice.
- Running our program shows a list sorted by string
-length, as desired.
-
+
|
-
+ |
$ go run sorting-by-functions.go
-[kiwi peach banana]
- |
-
-
-
-
- By following this same pattern of creating a custom
-type, implementing the three Interface methods on that
-type, and then calling sort.Sort on a collection of that
-custom type, we can sort Go slices by arbitrary
-functions.
-
- |
-
-
-
+[kiwi peach banana]
+[{TJ 25} {Jax 37} {Alex 72}]
|
@@ -167,7 +183,7 @@ functions.