Задать вопрос
@nano_e_t_4

Как отсортировать структуру по произвольному полю?

Всем привет
Есть структура
type bla-bla struct {
   a float64
   b float64
   c float64
   d float64
}


и есть массив таких структур:
func main {
  var la []bla-bla
  var la-la bla-bla
  struct1 := la-la{a: 1.0, b: 3.0, c:3.0, d:1.0}
  struct2 := la-la{a: 0.0, b: 5.0, c:3.0, d:2.0}
  struct3 := la-la{a: 8.0, b: 1.0, c:4.0, d:11.0}
  struct4 := la-la{a: 2.0, b: 0.0, c:3.0, d:7.0}
  la = append(la, struct1)
  la = append(la, struct2)
  la = append(la, struct3)
  la = append(la, struct4)
}


как можно их сортировать по нужному мне полю?
то есть нужна функция вида:
func sort_structs(la-la []Queries, sort_field) {
  //some_code
}

к примеру, один раз нужно отсортировать ее по полю a. Другой раз по полю c. И так далее

сама функция была написана но для [](map[string]interface{}). Сортирую значения, потом возвращаю соответствующие ключи. Перенес эту функцию на работу со структурой, но беда в том, что не знаю как задавать произвольное поле для сортировки.
Если кто сталкивался или знает, подскажите плз
  • Вопрос задан
  • 1865 просмотров
Подписаться 1 Оценить 5 комментариев
Пригласить эксперта
Ответы на вопрос 2
bitver
@bitver
Крч пригорело...
Вот документация стандартной библиотеки: https://golang.org/pkg/sort/
Вот выжимка, для особых:
раз
package main

import (
	"fmt"
	"sort"
)

// A couple of type definitions to make the units clear.
type earthMass float64
type au float64

// A Planet defines the properties of a solar system object.
type Planet struct {
	name     string
	mass     earthMass
	distance au
}

// By is the type of a "less" function that defines the ordering of its Planet arguments.
type By func(p1, p2 *Planet) bool

// Sort is a method on the function type, By, that sorts the argument slice according to the function.
func (by By) Sort(planets []Planet) {
	ps := &planetSorter{
		planets: planets,
		by:      by, // The Sort method's receiver is the function (closure) that defines the sort order.
	}
	sort.Sort(ps)
}

// planetSorter joins a By function and a slice of Planets to be sorted.
type planetSorter struct {
	planets []Planet
	by      func(p1, p2 *Planet) bool // Closure used in the Less method.
}

// Len is part of sort.Interface.
func (s *planetSorter) Len() int {
	return len(s.planets)
}

// Swap is part of sort.Interface.
func (s *planetSorter) Swap(i, j int) {
	s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
}

// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
func (s *planetSorter) Less(i, j int) bool {
	return s.by(&s.planets[i], &s.planets[j])
}

var planets = []Planet{
	{"Mercury", 0.055, 0.4},
	{"Venus", 0.815, 0.7},
	{"Earth", 1.0, 1.0},
	{"Mars", 0.107, 1.5},
}

// ExampleSortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.
func main() {
	// Closures that order the Planet structure.
	name := func(p1, p2 *Planet) bool {
		return p1.name < p2.name
	}
	mass := func(p1, p2 *Planet) bool {
		return p1.mass < p2.mass
	}
	distance := func(p1, p2 *Planet) bool {
		return p1.distance < p2.distance
	}
	decreasingDistance := func(p1, p2 *Planet) bool {
		return !distance(p1, p2)
	}

	// Sort the planets by the various criteria.
	By(name).Sort(planets)
	fmt.Println("By name:", planets)

	By(mass).Sort(planets)
	fmt.Println("By mass:", planets)

	By(distance).Sort(planets)
	fmt.Println("By distance:", planets)

	By(decreasingDistance).Sort(planets)
	fmt.Println("By decreasing distance:", planets)

}
два!
package main

import (
	"fmt"
	"sort"
)

type Grams int

func (g Grams) String() string { return fmt.Sprintf("%dg", int(g)) }

type Organ struct {
	Name   string
	Weight Grams
}

type Organs []*Organ

func (s Organs) Len() int      { return len(s) }
func (s Organs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

// ByName implements sort.Interface by providing Less and using the Len and
// Swap methods of the embedded Organs value.
type ByName struct{ Organs }

func (s ByName) Less(i, j int) bool { return s.Organs[i].Name < s.Organs[j].Name }

// ByWeight implements sort.Interface by providing Less and using the Len and
// Swap methods of the embedded Organs value.
type ByWeight struct{ Organs }

func (s ByWeight) Less(i, j int) bool { return s.Organs[i].Weight < s.Organs[j].Weight }

func main() {
	s := []*Organ{
		{"brain", 1340},
		{"heart", 290},
		{"liver", 1494},
		{"pancreas", 131},
		{"prostate", 62},
		{"spleen", 162},
	}

	sort.Sort(ByWeight{s})
	fmt.Println("Organs by weight:")
	printOrgans(s)

	sort.Sort(ByName{s})
	fmt.Println("Organs by name:")
	printOrgans(s)

}

func printOrgans(s []*Organ) {
	for _, o := range s {
		fmt.Printf("%-8s (%v)\n", o.Name, o.Weight)
	}
}


Если прям совсем чуда хотите - пишите через рефлексию. И это не совет, а крайний случай, никому бы не посоветовал её использовать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы