Go: Is there a way to avoid implementing a complete sort.Interface for fragments of structures?

If I have an array / fragment of structures in Go and you want to sort them using the sort package, it seems to me that I need to implement the entire sort interface, which contains 3 methods:

  • Len
  • Exchange
  • Less

It seems that Len and Swap should always have the same implementation regardless of the type of structure in the array.

Is there a way to avoid using Len and Swap to implement each time, or is it just a limitation on the lack of Generics in Go?

+5
source share
4 answers

. Len() Swap() . , len() Go swap() . , , , BTrees. - Sort() (, quicksort, ).

+5

, , Len Swap . , , .

.

package main

import (
    "sort"
)

type T struct {
    Foo int
    Bar int
}

// TVector is our basic vector type.
type TVector []T

func (v TVector) Len() int {
    return len(v)
}

func (v TVector) Swap(i, j int) {
    v[i], v[j] = v[j], v[i]
}

// default comparison.
func (v TVector) Less(i, j int) bool {
    return v[i].Foo < v[j].Foo
}

// TVectorBarOrdered embeds TVector and overrides
// its Less method so that it is ordered by the Bar field.
type TVectorBarOrdered struct {
    TVector
}

func (v TVectorBarOrdered) Less(i, j int) bool {
    return v.TVector[i].Bar < v.TVector[j].Bar
}

// TVectorArbitraryOrdered sorts in normal or reversed
// order depending on the order of its Reversed field.
type TVectorArbitraryOrdered struct {
    Reversed bool
    TVector
}

func (v TVectorArbitraryOrdered) Less(i, j int) bool {
    if v.Reversed {
        i, j = j, i
    }
    return v.TVector[i].Foo < v.TVector[j].Foo
}

func main() {
    v := []T{{1, 3}, {0, 6}, {3, 2}, {8, 7}}
    sort.Sort(TVector(v))
    sort.Sort(TVectorBarOrdered{v})
    sort.Sort(TVectorArbitraryOrdered{true, v})
}
+7

, github.com/bradfitz/slice . , ( "" ):

, , Len Swap.

, , , , - :

type points []point

func (p []points) Len() int      { return len(p) }
func (p []points) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p []points) Less(i, j int) bool {
        // custom, often multi-line, comparison code here
}

gofmt type func . , .

, :

, Len Swap [slice]

, ( strings.NewReplacer), , :

type pairByLen []string

func (p pairByLen) Len() int           { return len(p) / 2 }
func (p pairByLen) Less(i, j int) bool { return len(p[i*2]) > len(p[j*2]) }
func (p pairByLen) Swap(i, j int) {
        p[i*2], p[j*2] = p[j*2], p[i*2]
        p[i*2+1], p[j*2+1] = p[j*2+1], p[i*2+1]
}

, , github.com/bradfitz/slice. , , . (, , ), .

0

All Articles