Функция, которая возвращает минимальное значение среза на основе поля структуры? - PullRequest
0 голосов
/ 10 марта 2019

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

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

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

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

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

Спасибо!

1 Ответ

0 голосов
/ 11 марта 2019

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

Вариант 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 & 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 := &pc.patients[0]

    // O(N) complexity!
    for i, p := range pc.patients {
        if p.bodyTemp < patientWithMinTemp.bodyTemp {
            patientWithMinTemp = &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 пациентов), правильный способ - ввести в приложение хранилище, поддерживающее индексы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...