sort.Sort în Go

Sortează orice colecție care implementează sort.Interface (Len, Less, Swap); Stable păstrează ordinea elementelor egale.

Sintaxă
import "sort"

type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(i, j int)
}

func Sort(data Interface)
func Stable(data Interface)   // Go 1.2

Ce face sort.Sort

sort.Sort este modul clasic de a sorta în Go: tipul tău definește trei metode, Len() (câte elemente), Less(i, j) (dacă elementul i vine înaintea lui j) și Swap(i, j) (interschimbare). Astfel sortezi orice structură indexată, nu doar slice-uri.

sort.Stable face același lucru, dar păstrează ordinea inițială a elementelor egale. sort.Sort nu garantează asta.

Pachetul are și tipuri gata făcute (sort.IntSlice, sort.StringSlice) și sort.Reverse(data), care inversează ordinea. Pentru slice-uri obișnuite, în cod nou folosește slices.SortFunc și slices.SortStableFunc, mai scurte.

Parametri

Parametru Descriere
data Colecția, de un tip care are metodele Len, Less și Swap.

Ce returnează

Nimic; colecția este sortată pe loc.

Exemple

Exemplul 1: Orașe sortate după populație

package main

import (
    "fmt"
    "sort"
)

type Oras struct {
    Nume     string
    Locuitori int
}

type DupaPopulatie []Oras

func (o DupaPopulatie) Len() int           { return len(o) }
func (o DupaPopulatie) Less(i, j int) bool { return o[i].Locuitori < o[j].Locuitori }
func (o DupaPopulatie) Swap(i, j int)      { o[i], o[j] = o[j], o[i] }

func main() {
    orase := []Oras{{"Iași", 271692}, {"Cluj-Napoca", 286598}, {"Timișoara", 250849}, {"Constanța", 263688}}
    sort.Sort(DupaPopulatie(orase))
    for _, o := range orase {
        fmt.Printf("%-12s %d\n", o.Nume, o.Locuitori)
    }
}

Rezultat

Timișoara    250849
Constanța    263688
Iași         271692
Cluj-Napoca  286598

Exemplul 2: Ordine inversă cu sort.Reverse și sortare stabilă

package main

import (
    "fmt"
    "sort"
)

func main() {
    note := []int{7, 10, 5, 9, 8}
    sort.Sort(sort.Reverse(sort.IntSlice(note)))
    fmt.Println(note)

    cuvinte := []string{"mere", "pere", "nuci", "kiwi"}
    sort.Stable(sort.StringSlice(cuvinte))
    fmt.Println(cuvinte)
}

Rezultat

[10 9 8 7 5]
[kiwi mere nuci pere]

Greșeli frecvente

  • Definești metodele pe pointer (func (o *DupaPopulatie) Len()) și apoi transmiți valoarea: tipul nu mai implementează sort.Interface și codul nu compilează.
  • Scrii trei metode pentru fiecare criteriu nou de sortare: pentru slice-uri, slices.SortFunc cu o funcție anonimă e mult mai simplu.

Comenzi înrudite

  • sort.Slice: Sortează un slice de orice tip după o funcție less(i, j); SliceStable păstrează ordinea elementelor egale.
  • slices.SortFunc: Sortează un slice după o funcție de comparare care returnează negativ, zero sau pozitiv; SortStableFunc păstrează ordinea celor egali.
  • container/heap.Init: Funcțiile de bază ale unui heap (coadă de priorități): Init îl organizează, Push adaugă, Pop scoate elementul cel mai mic.