Golang: Sorting a Slice of 2 Struct Types

Leveraging an interface, we can implement the sort interface to effectively sort a slice of anything in golang

Go-aviator

TLDR;

Take me to the google playground!!!

Full Version

I didn't see great examples of this while googling, so I thought I'd write a short blog post about it.

First, our structs.

type Veggie struct {
  Name string
  Foo string
}

type Fruit struct {
  Name string
  Bar string
}

You'll notice I purposefully made Fruit and Veggie and Foo/Bar attributes so they could not be type converted - no cheating! However, they share an attribute called Name that we'll eventually sort by.

Next, we're going to define an interface that both Fruit and Veggie implement. (WARNING: my naming conventions are inspired by my rails background so bear with me)

// Nameable is an interface - when implemented - allows the underlying struct to be sorted by the return value 
type Nameable interface {
  GetName() string
}

// GetName implements the Nameable interface on Veggie
func (v Veggie) GetName() string {
  return v.Name
}

// GetName implements the Nameable interface on Fruit
func (f Fruit) GetName() string {
  return f.Name
}

Cool, so now both our Fruit and Veggie structs implement the Nameable interface.

Next, we're going to create a slice type that allows us to create a slice of anything that implements the Nameable interface.

type Nameables []Nameable

Lastly, we implement the sort interface on our Nameables type.

func (n Nameables) Len() int {
  return len(n)
}

func (n Nameables) Less(i, j int) bool {
  return n[i].GetName() < n[j].GetName()
}

func (n Nameables) Swap(i, j int) {
  n[i], n[j] = n[j], n[i]
}

Cool, so assuming this is all implemented, what does our code look like?

func main() {
    carrot := Veggie{Name: "Carrot", Foo: "Root"}
    apple := Fruit{Name: "Apple", Bar: "Seed"}

    combined := Nameables{carrot, apple}

    sort.Sort(combined)

    fmt.Printf("Conversion: %v", combined)
}

And after running this, we should see: Conversion: [{Apple Seed} {Carrot Root}]

You can tell it's neat by the way that it is! How neat is that?