github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/sort/subsort/precursor_ideas_test.go (about)

     1  package subsort
     2  
     3  // File contains examples of other strategies for flexible sorting.
     4  // I considered and rejected these examples.
     5  // Then I developed my own versatile sorting helper.
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"sort"
    11  	"testing"
    12  )
    13  
    14  //--------------------------------------------
    15  // Precursor 1
    16  
    17  // A type, containing function headers for the sort interface.
    18  type sortI struct {
    19  	l    int // not len(), but its value
    20  	less func(int, int) bool
    21  	swap func(int, int)
    22  }
    23  
    24  // The methods of the sort interface
    25  // are now satisfied, using the *members* of the struct.
    26  func (s *sortI) Len() int {
    27  	return s.l
    28  }
    29  
    30  func (s *sortI) Less(i, j int) bool {
    31  	return s.less(i, j)
    32  }
    33  
    34  func (s *sortI) Swap(i, j int) {
    35  	s.swap(i, j)
    36  }
    37  
    38  // SortI can now be used as follows:
    39  //   sort.Sort( &sortI{} )
    40  
    41  // SortF wraps the construction
    42  // and usage of a sortI instance.
    43  func SortF(Len int, Less func(int, int) bool, Swap func(int, int)) {
    44  	si := &sortI{l: Len, less: Less, swap: Swap}
    45  	sort.Sort(si)
    46  }
    47  
    48  // We can now take any int slice
    49  // and construct two-and-a-half closures with it
    50  // and pass the closures (with our int slice implicitly piggypacked) to SortF
    51  func TestSortI_demo(t *testing.T) {
    52  	ints := []int{3, 4, 1, 7, 0}
    53  	SortF(len(ints), func(i, j int) bool {
    54  		return ints[i] < ints[j]
    55  	}, func(i, j int) {
    56  		ints[i], ints[j] = ints[j], ints[i]
    57  	})
    58  	want := fmt.Sprintf("%#v", []int{0, 1, 3, 4, 7})
    59  	got := fmt.Sprintf("%#v", ints)
    60  	if want != got {
    61  		t.Errorf("wanted vs got: \n%v \n%v", want, got)
    62  	}
    63  }
    64  
    65  // This approach still needs typespecific variations of sortI.
    66  // And it requires the closure notation.
    67  
    68  //
    69  //--------------------------------------------
    70  
    71  // precursor2 - using interface{}
    72  // copyAndSort() first produces a copy,
    73  // the copy containing only the desired data.
    74  // Then this subset copy is sorted.
    75  // Sadly, the argument of type []interface{} is expensive to create
    76  // from calling packages. It mostly involves previous copying element by element
    77  // thus genericism causes *two* rounds of copying.
    78  // For this reason we prefer the SortByVal() func,
    79  // width the only downside, that the preparation of the subset slice
    80  // needs to be done by the calling package.
    81  // Otherwise we are left with only *one* round of copying
    82  // and without the need for reflection.
    83  func demo__copyAndSort(sArg []interface{}, fieldname string) []SortedByStringVal {
    84  
    85  	copyOfSubset := []SortedByStringVal{}
    86  	for i := 0; i < len(sArg); i++ {
    87  		lp := sArg[i]
    88  		immutable := reflect.ValueOf(lp)
    89  		// reflect.Value.String() does not panic upon non-strings.
    90  		// Instead it returns "<type value>" for non-string
    91  		dynVal := immutable.FieldByName(fieldname).String()
    92  		copyOfSubset = append(copyOfSubset, SortedByStringVal{IdxOrig: i, Val: dynVal})
    93  	}
    94  
    95  	wrapperSortable := sliceSortableStringAsc(copyOfSubset)
    96  	sort.Sort(wrapperSortable)
    97  	unwrap := []SortedByStringVal(wrapperSortable)
    98  	return unwrap
    99  
   100  }
   101  
   102  //
   103  //
   104  func demo__GetFieldValueByName() {
   105  	type MyStruct struct {
   106  		SortBy string
   107  	}
   108  	myStruct := MyStruct{"001"}
   109  	immutable := reflect.ValueOf(myStruct)
   110  	val := immutable.FieldByName("SortBy").String()
   111  	_ = val
   112  }