首页 > 其他分享 >Go - Sorting Arrays or Slices

Go - Sorting Arrays or Slices

时间:2023-10-08 10:55:06浏览次数:43  
标签:sort integers Sorting people Arrays Slice slice Go ByAge

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

相关文章

  • Go - Making Arrays and Slices Safe for Concurrent Use
    Problem: Youwanttomakearraysandslicessafeforconcurrentusebymultiplegoroutines.Solution: Useamutexfromthesynclibrarytosafeguardthearrayorslice.Lockthearrayorslicebeforemodifyingit,andunlockitaftermodificationsarema......
  • 使用hugo+github搭建免费个人博客
    使用hugo+github搭建免费个人博客前提条件win11电脑一台电脑安装了git电脑安装了hugogithub账号一个个人博客本地搭建初始化一个博客打开cmd窗口,使用hugo新建一个博客工程hugonewsiteblogtest 1下载主题主题官网:themes.gohugo.io在上面找一个主题,我这里找......
  • go笔记
    1、Go语言中的变量、函数、常量名称的首字母也可以大写,如果首字母大写,则表示它可以被其它的包访问(类似于 Java 中的public);如果首字母小写,则表示它只能在本包中使用(类似于Java中private)。......
  • slices in Go 1.21
    Go1.21中新增的slices包中提供了很多与切片相关的函数,适用于任意类型的切片。本文内容来自官方文档BinarySearch函数签名如下:funcBinarySearch[S~[]E,Ecmp.Ordered](xS,targetE)(int,bool)BinarySearch在已排序的切片中搜索target并返回找到target的位置,或......
  • Golang HOT100 做题记录
     LeetCode热题100  1.两数之和题目大意:给出一个数字的数[]num,一个目标值target。在数组中,找出两数之和为目标值的下标,任意输出一个答案。例子:num[]={0,2,3,4,2},target=4,输出:[]int{0,3}注意点:1.不能重复,如上不能为[]int{1,1},2.注意数组中重复数字处理 ......
  • Go - Remove values from a slice
    Totakeoutthefirstelementoftheslice:numbers:=[]int{3,14,159,26,53,58}numbers=numbers[1:]//removeelement0To takeoutthelastelementoftheslice:numbers:=[]int{3,14,159,2......
  • Go - Insert values into a slice
    Thereisnobuilt-infunctionforinsertion,butyoucanstilluseappendforthetask.Let’ssayyouwanttoinsertthenumber1000betweenelementsatindex2and3,whichareints159and26,respectively:numbers:=[]int{3,14,159,......
  • Go - Defining Metadata for Struct Fields
    Problem: Youwanttodefinemetadatatodescribethestructfields.Solution: Usestructtagstodefinemetadataandthereflectpackagetoaccessthetags. Oneverycommonplaceyoufindthisisinthejsonpackage:typePersonstruct{......
  • CF1856B Good Arrays
    题意简述:给定一个序列\(a\),我们定义一个序列\(b\)是好的当且仅当对于\(1\dotsn\)内的每一个\(i\),\(a_i\neqb_i\)且\(\sum_{i=1}^na_i=\sum_{i=1}^nb_i\)(\(a_i\),\(b_i\)均为正整数)。现在有\(T\)组数据,每组数据给定\(n\)和序列\(a\),判断是否存在一个合法的序......
  • Go 项目代码布局
    Go项目代码布局目录Go项目代码布局一、Go语言“创世项目”结构1.1src目录结构三个特点二、Go项目布局演进2.1演进一:Go1.4版本删除pkg这一中间层目录并引入internal目录2.2演进二:Go1.6版本增加vendor目录2.3演进三:Go1.13版本引入go.mod和go.sum三、现在Go......