Sort
Sort a map by key or value
https://yourbasic.org/golang/sort-map-keys-values/
- A map is an unordered collection of key-value pairs.
- If you need a stable iteration order, you must maintain a separate data structure.
https://go.dev/play/p/UkOF5Aqad7M?v=gotip
package main
import (
"fmt"
"sort"
)
func main() {
m := map[string]int{"Alice": 23, "Eve": 2, "Bob": 25}
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, m[k])
}
}
// Alice 23
// Bob 25
// Eve 2
Golang Sorting and Custom Sorting by functions
https://www.callicoder.com/golang-sorting-custom-functions/
Sorting a Slice of Strings, Integers, or Floats in Go
https://go.dev/play/p/W9rKDuBl5m0?v=gotip
package main
import (
"fmt"
"sort"
)
func main() {
// Sorting a slice of Strings
strs := []string{"quick", "brown", "fox", "jumps"}
sort.Strings(strs)
fmt.Println("Sorted strings: ", strs)
// Reverse order
sort.Sort(sort.Reverse(sort.StringSlice(strs)))
fmt.Println("Sorted strings in reverse order: ", strs)
// Sorting a slice of Integers
ints := []int{56, 19, 78, 67, 14, 25}
sort.Ints(ints)
fmt.Println("Sorted integers: ", ints)
// Reverse order
sort.Sort(sort.Reverse(sort.IntSlice(ints)))
fmt.Println("Sorted integers in reverse order: ", ints)
// Sorting a slice of Floats
floats := []float64{176.8, 19.5, 20.8, 57.4}
sort.Float64s(floats)
fmt.Println("Sorted floats: ", floats)
// Reverse order
sort.Sort(sort.Reverse(sort.Float64Slice(floats)))
fmt.Println("Sorted floats in reverse order: ", floats)
}
// Sorted strings: [brown fox jumps quick]
// Sorted strings in reverse order: [quick jumps fox brown]
// Sorted integers: [14 19 25 56 67 78]
// Sorted integers in reverse order: [78 67 56 25 19 14]
// Sorted floats: [19.5 20.8 57.4 176.8]
// Sorted floats in reverse order: [176.8 57.4 20.8 19.5]
Sorting a slice using a comparator function in Go
Slice() and SliceStable() functions provided by the sort package. These are higher order functions that accept a less function as an argument:
func Slice(x interface{}, less func(i, j int) bool)
func SliceStable(x interface{}, less func(i, j int) bool)
當你使用 Slice() 函數時,不能保證排序是穩定的:相等的元素可能會與它們的原始順序顛倒。對於穩定排序,請使用 SliceStable()。
The less function is a comparator function that reports whether the element at index i should sort before the element at index j. If both less(i, j) and less(j, i) are false, then the elements at index i and j are considered equal.
https://go.dev/play/p/LEisON3mklz?v=gotip
package main
import (
"fmt"
"sort"
)
func main() {
// Sorting a slice of strings by length
strs := []string{"United States", "India", "France", "United Kingdom", "Spain"}
sort.Slice(strs, func(i, j int) bool {
return len(strs[i]) < len(strs[j])
})
fmt.Println("Sorted strings by length: ", strs)
// Stable sort
sort.SliceStable(strs, func(i, j int) bool {
return len(strs[i]) < len(strs[j])
})
fmt.Println("[Stable] Sorted strings by length: ", strs)
// Sorting a slice of strings in the reverse order of length
sort.SliceStable(strs, func(i, j int) bool {
return len(strs[j]) < len(strs[i])
})
fmt.Println("[Stable] Sorted strings by reverse order of length: ", strs)
}
// Sorted strings by length: [India Spain France United States United Kingdom]
// [Stable] Sorted strings by length: [India Spain France United States United Kingdom]
// [Stable] Sorted strings by reverse order of length: [United Kingdom United States France India Spain]
Sorting a slice of structs using a comparator function
https://go.dev/play/p/G1YiOl-tmOR?v=gotip
package main
import (
"fmt"
"sort"
)
type User struct {
Name string
Age int
}
func main() {
// Sorting a slice of structs by a field
users := []User{
{
Name: "Rajeev",
Age: 28,
},
{
Name: "Monica",
Age: 31,
},
{
Name: "John",
Age: 56,
},
{
Name: "Amanda",
Age: 16,
},
{
Name: "Steven",
Age: 28,
},
}
// Sort users by their age
sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
fmt.Println("Sorted users by age: ", users)
// Stable sort
sort.SliceStable(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
fmt.Println("Sorted users by age: ", users)
}
// Sorted users by age: [{Amanda 16} {Rajeev 28} {Steven 28} {Monica 31} {John 56}]
// Sorted users by age: [{Amanda 16} {Rajeev 28} {Steven 28} {Monica 31} {John 56}]
Custom sorting by implementing sort.Interface
To enable custom sorting of a collection of any type, you need to define a corresponding type that implements the generic Interface provided by the sort package. The Interface contains the following methods:
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with index i must sort before the element with index j.
// If both Less(i, j) and Less(j, i) are false, then the elements at index i and j are considered equal.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
After implementing the above Interface, you can use the Sort() or Stable() functions that sort any collection that implements the sort.Interface interface.
https://go.dev/play/p/0RN-hI10p4k?v=gotip
package main
import (
"fmt"
"sort"
)
type User struct {
Name string
Age int
}
// Define a collection type that implements sort.Interface
type UsersByAge []User
func (u UsersByAge) Len() int {
return len(u)
}
func (u UsersByAge) Swap(i, j int) {
u[i], u[j] = u[j], u[i]
}
func (u UsersByAge) Less(i, j int) bool {
return u[i].Age < u[j].Age
}
func main() {
users := []User{
{
Name: "Rajeev",
Age: 28,
},
{
Name: "Monica",
Age: 31,
},
{
Name: "John",
Age: 56,
},
{
Name: "Amanda",
Age: 16,
},
{
Name: "Steven",
Age: 28,
},
}
// Sorting a slice of users by age (Sort may place equal elements in any order in the final result)
sort.Sort(UsersByAge(users))
fmt.Println("Sorted users by age: ", users)
// Stable Sorting (Stavle sort preserves the original input order of equal elements)
sort.Stable(UsersByAge(users))
fmt.Println("[Stable] Sorted users by age: ", users)
}
// Sorted users by age: [{Amanda 16} {Rajeev 28} {Steven 28} {Monica 31} {John 56}]
// [Stable] Sorted users by age: [{Amanda 16} {Rajeev 28} {Steven 28} {Monica 31} {John 56}]
https://go.dev/play/p/pfIo6NOBeTX?v=gotip
package main
import (
"fmt"
"sort"
)
type sortEnvelopes [][]int
func (s sortEnvelopes) Len() int {
return len(s)
}
func (s sortEnvelopes) Less(i, j int) bool {
if s[i][0] == s[j][0] {
// 遇到w相同的情況, 則按照高度進行降序排序
return s[i][1] > s[j][1]
}
// 對寬度w進行升序排序
return s[i][0] < s[j][0]
}
func (s sortEnvelopes) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func main() {
envelopes := [][]int{{5, 4}, {6, 4}, {6, 7}, {2, 3}}
sort.Sort(sortEnvelopes(envelopes))
fmt.Println(envelopes)
}
// [[2 3] [5 4] [6 7] [6 4]]