Problem: You want to sort elements in an array or slice.
Solution: For int , float64 , and string arrays or slices you can use sort.Ints , sort.Float64s , and sort.Strings . You can also use a custom comparator by using sort.Slice . For structs, you can create a sortable interface by implementing the sort.Interface interface and then using sort.Sort to sort the array or slice.
integers := [] int { 3 , 14 , 159 , 26 , 53 } floats := [] float64 { 3.14 , 1.41 , 1.73 , 2.72 , 4.53 } strings := [] string { "the" , "quick" , "brown" , "fox" , "jumped" } sort . Ints ( integers ) sort . Float64s ( floats ) sort . Strings ( strings ) fmt . Println ( integers ) fmt . Println ( floats ) fmt . Println ( strings )
[3 14 26 53 159] [1.41 1.73 2.72 3.14 4.53] [brown fox jumped quick the]
This is sorted in ascending order. What if you want to sort it in descending order? There is no ready - made function to sort in descending order, but you can easily use a simple for loop to reverse the sorted slice:
for i := len ( integers ) / 2 - 1 ; i >= 0 ; i - - { opp := len ( integers ) - 1 - i integers [ i ], integers [ opp ] = integers [ opp ], integers [ i ] } fmt . Println ( integers )
Simply find the middle of the slice, and then using a loop, exchange the elements with their opposite side, starting from that middle. If you run the preceding snippet, this is what you will get:
[159 53 26 14 3]
You can also use the sort.Slice function, passing in your less function:
sort . Slice ( floats , func ( i , j int ) bool { return floats [ i ] > floats [ j ] }) fmt . Println ( floats )
This will produce the following output:
[4.53 3.14 2.72 1.73 1.41]
The less function, the second parameter in the sort.Slice function, takes in two parameters i and j , indices of the consecutive elements of the slice. It’s supposed to return true if the element at i is less than the element at j when sorting.
What if the elements are the same? Using sort.Slice means the original order of the elements might be reversed (or remain the same). If you want the order to be consistently the same as the original, you can use sort.SliceStable .
The sort.Slice function works with slices of any type, so this means you can also sort custom structs:
people := [] Person { { "Alice" , 22 }, { "Bob" , 18 }, { "Charlie" , 23 }, { "Dave" , 27 }, { "Eve" , 31 }, } sort . Slice ( people , func ( i , j int ) bool { return people [ i ]. Age < people [ j ]. Age }) fmt . Println ( people )
If you run the code you will get the following output, with the people slice sorted according to the ages of the people:
[{Bob 18} {Alice 22} {Charlie 23} {Dave 27} {Eve 31}]
Another way of sorting structs is by implementing the sort.Interface . Here’s how you can do this for the Person struct:
type Person struct { Name string Age int } type ByAge [] Person func ( a ByAge ) Len () int { return len ( a ) } func ( a ByAge ) Less ( i , j int ) bool { return a [ i ]. Age < a [ j ]. Age } func ( a ByAge ) Swap ( i , j int ) { a [ i ], a [ j ] = a [ j ], a [ i ] }
You want to sort a slice of structs, so you need to associate the interface functions to the slice, not the struct. Create a type named ByAge that is a slice of Person structs. Next, you associate the Len , Less , and Swap functions to ByAge , making it a struct that implements sort.Interface . The Less method here is the same as the one used in the sort.Slice function earlier.
Using this is quite simple. You cast people to ByAge , and pass that into sort.Sort
people := [] Person { { "Alice" , 22 }, { "Bob" , 18 }, { "Charlie" , 23 }, { "Dave" , 27 }, { "Eve" , 31 }, } sort . Sort ( ByAge ( people )) fmt . Println ( people )
If you run this code, you will see the following results:
[{Bob 18} {Alice 22} {Charlie 23} {Dave 27} {Eve 31}]
Implementing sort.Interface is a bit long - winded, but there are certainly some advantages. For one, you can use sort.Reverse to sort by descending order:
sort . Sort ( sort . Reverse ( ByAge ( people ))) fmt . Println ( people )
This produces the following output:
[{Eve 31} {Dave 27} {Charlie 23} {Alice 22} {Bob 18}]
You can also use the sort.IsSorted function to check if the slice is already sorted:
sort . IsSorted ( ByAge ( people )) // true if it's sorted
The biggest advantage, though, is that using sort.Interface is a lot more performant than using sort.Slice.
As you can see, using sort.Interface is more efficient. This is because sort.Slice uses any as the first parameter. This means it takes in any structs but is less efficient.
标签:sort,integers,Sorting,people,Arrays,Slice,slice,Go,ByAge From: https://www.cnblogs.com/zhangzhihui/p/17748369.html