Использование findmin () в данных из массива, состоящего из изменяемых элементов структуры - Юлия - PullRequest
3 голосов
/ 30 марта 2020

Предположим, у меня есть следующая структура:

mutable struct Car
    load
    locale
    availability
    odometer
end

И я создал массив:

fleet = Vector{Car}(undef, num_cars)

for i in 1:num_cars
   a, b, c, d = rand(4)
   fleet[i] = Car(a, b, c, d)
end

Как найти наименьшее (с findmin или аналогичное) или наибольшее (с?) Значение, например, от одометра всех автомобилей в моем массиве?

В принципе, я хочу иметь возможность использовать условные операторы со структурными массивами, например: Для каждого элемента в моем массиве struct получите те, которые для данных удовлетворяют условию, и, исходя из них, получите минимальное значение для других данных.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 31 марта 2020

Найти минимальное значение довольно просто, используя функцию minimum с аргументом отображения:

julia> minimum(x->x.odometer, fleet)
0.08468003971220694

Если вам также нужен индекс минимума, вы можете использовать функцию findmin , К сожалению, по какой-то причине это не поддерживает аргумент функции, поэтому вам необходимо создать временный массив и применить к нему findmin:

julia> findmin(getfield.(fleet, :odometer))
(0.08468003971220694, 1)

Вы также можете использовать getproperty вместо getfield, они делают то же самое для вашей структуры, я не уверен, что предпочтительнее. Вероятно, наиболее идиоматическим решением c было бы определение функций доступа вместо непосредственного использования значений полей. Например:

odometer(car::Car) = car.odometer
minimum(odometer, fleet)
findmin(odometer.(fleet))

Для максимальных значений используйте maximum и findmax.

1 голос
/ 31 марта 2020

Джулия о производительности.

Вам следует избегать использования нетипизированных struct s, поэтому ваше определение типа должно быть:

mutable struct Car
    load::Float64
    locale::Float64
    availability::Float64
    odometer::Float64
end

Код для создания Vector может быть короче:

cars = [Car(rand(4)...) for _ in 1:5]

Наиболее эффективный способ найти индекс минимального элемента:

julia> Base.isless(c1::Car,c2::Car) = c1.odometer < c2.odometer

julia> findmin(cs)
(Car(0.7623514815463603, 0.7523019237133661, 0.37422766075278413, 0.49830949323733464), 3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...