Функция, которая возвращает минимальное значение фрагмента на основе поля структуры?

#go

#Вперед

Вопрос:

У меня есть структура Go, такая как:

 type patient struct{
    patientID int
    age int
    bodyTemp int
    numberVaccines int
    recordID int
}
  

Как я могу написать функцию, которая возвращает минимальное значение в фрагменте patient , выбрав поле, которое меня интересует?

Я бы назвал это как:

 someSlice := []patient{patient{...},...,...}
fmt.Printf("Patient lowest temp: %v", someSlice.GetMin(bodyTemp)
  

Спасибо!

Комментарии:

1. Я не понимаю. Минимум чего?

2. Здесь не хватает чего-то важного. Ваша структура имеет ОДИН bodyTemp. Итак, вы хотите получить минимальное значение ОДНОГО значения? Это ваш вопрос, как вы описали его здесь.

3. Извините, ребята, я виноват. Исправлен вопрос.

4. Здесь вам придется выполнить минимальное количество программирования.

5. То, что вы пытаетесь, можно было бы выполнить с помощью отражения, но, пожалуйста, не делайте этого. Это медленно и невероятно сложно для чтения. Правильный подход — это один метод для каждого поля.

Ответ №1:

Как уже было написано в комментариях, вы можете сделать это с помощью отражения, но в этом нет необходимости из-за снижения производительности.

Вариант 1

Что касается быстрого решения, я предлагаю вам реализовать оболочку среза пациентов, которая отвечает за хранение и поиск нужных вам данных по указанным критериям (для каждого поля свой метод). Это также не связано с производительностью, потому что в вашем случае вам нужно выполнить поиск минимального значения, которое имеет сложность O (N) (вам нужно перебрать все элементы в фрагменте).

 package main

import (
    "errors"
    "fmt"
)

var (
    ErrPatientsContainerIsEmpty = errors.New("patients container is empty")
)

type Patient struct{
    patientID int
    age int
    bodyTemp int
    numberVaccines int
    recordID int
}

type PatientsContainer struct {
    patients []Patient
}

func NewPatientsContainer() *PatientsContainer {
    patients := make([]Patient, 0)
    return amp; PatientsContainer{
        patients: patients,
    }
}

func (pc *PatientsContainer) Add(p Patient) {
    pc.patients = append(pc.patients, p)
}

func (pc *PatientsContainer) WithMinTemp() (*Patient, error) {
    if len(pc.patients) == 0 {
        return nil, ErrPatientsContainerIsEmpty
    }

    patientWithMinTemp := amp;pc.patients[0]

    // O(N) complexity!
    for i, p := range pc.patients {
        if p.bodyTemp < patientWithMinTemp.bodyTemp {
            patientWithMinTemp = amp;pc.patients[i]
        }
    }

    return patientWithMinTemp, nil
}

func main() {
    // some patients data for testing
    patients := []Patient{
        {
            recordID: 1,
            bodyTemp: 37,
        },
        {
            recordID: 2,
            bodyTemp: 36,
        },
            {
            recordID: 3,
            bodyTemp: 38,
        },  
    }

    pc := NewPatientsContainer()

    // Add to container
    for _, p := range patients {
        pc.Add(p)
    }

    patientWithMinTemp, err := pc.WithMinTemp()
    if err != nil {
        // handle an error
        panic(err)
    }

    fmt.Println(patientWithMinTemp.recordID)
}
  

Вариант 2

Если мы говорим о приложении с большим набором данных (не 50 пациентов), правильный способ — ввести в приложение хранилище, поддерживающее индексы.

Ответ №2:

Используйте функцию sort.Slice, описанную здесь: https://pkg.go.dev/sort

 patients := []patient{patient{...},...,...}    
sort.Slice(patients, func(i, j int) bool {
   return patients[i].bodyTemp < patients[j].bodyTemp
})
minBodyTempPatient := patients[0]