github.com/rolandhe/saber@v0.0.4/utils/sortutil/sort.go (about)

     1  // Package sortutil, sort  tool
     2  //
     3  // Copyright 2023 The saber Authors. All rights reserved.
     4  
     5  // Package sortutil 通用的对象数组快速排序
     6  // 使用方式
     7  //
     8  //  type req struct {
     9  //	   val    string
    10  //	   sortId int
    11  //  }
    12  //
    13  //	var data []*req
    14  //
    15  //	data = append(data, &req{"a", 3})
    16  //	data = append(data, &req{"b", 1})
    17  //	data = append(data, &req{"m", 9})
    18  //
    19  //	Cmp[*req](func(p1, p2 **req) bool {
    20  //		return (*p1).sortId < (*p2).sortId
    21  //	}).Sort(data)
    22  //
    23  package sortutil
    24  
    25  import "sort"
    26  
    27  // 来自官方文档的例子,很巧妙的使用函数的方法实现类似泛型的排序,妙
    28  
    29  // Cmp 比较函数,比较 *T 类型的 p1 是否大于 p2
    30  type Cmp[T any] func(p1, p2 *T) bool
    31  
    32  // Sort is a method on the function type, Cmp, that sorts the argument slice according to the function.
    33  func (cmp Cmp[T]) Sort(data []T) {
    34  	ps := &sortHolder[T]{
    35  		data: data,
    36  		cmp:  cmp, // The Sort method's receiver is the function (closure) that defines the sort order.
    37  	}
    38  	sort.Sort(ps)
    39  }
    40  
    41  type sortHolder[T any] struct {
    42  	data []T
    43  	cmp  func(p1, p2 *T) bool // Closure used in the Less method.
    44  }
    45  
    46  // Len is part of sort.Interface.
    47  func (s *sortHolder[T]) Len() int {
    48  	return len(s.data)
    49  }
    50  
    51  // Swap is part of sort.Interface.
    52  func (s *sortHolder[T]) Swap(i, j int) {
    53  	s.data[i], s.data[j] = s.data[j], s.data[i]
    54  }
    55  
    56  // Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
    57  func (s *sortHolder[T]) Less(i, j int) bool {
    58  	return s.cmp(&s.data[i], &s.data[j])
    59  }