有数组时如何获取结构项的最大值?

时间:2019-09-18 06:18:04

标签: julia

我在Julia中具有以下结构,并用它创建一个数组。

julia>     struct myStruct
              a::Int
              b::Int
              c::String
           end

julia>     myArray = myStruct.(1:10,11:20,"ABC")
10-element Array{myStruct,1}:
 myStruct(1, 11, "ABC") 
 myStruct(2, 12, "ABC") 
 myStruct(3, 13, "ABC") 
 myStruct(4, 14, "ABC") 
 myStruct(5, 15, "ABC") 
 myStruct(6, 16, "ABC") 
 myStruct(7, 17, "ABC") 
 myStruct(8, 18, "ABC") 
 myStruct(9, 19, "ABC") 
 myStruct(10, 20, "ABC")

在Julia中我该怎么做才能获得a的最大值?

建议先获取一个带有该结构的前两个值的2列数组,然后使用findmax(my2colArray[:,1])来找到最大值吗?

我有三个问题要了解我该怎么做:

  1. 如果需要先获取数组,如何有效地获取两列数组?
  2. 如果不需要,我如何直接从结构数组中获得a的最大值?
  3. 该字符串最多包含50个字符,并且它们将是ASCII(无UTF-8)。我应该以某种方式固定字符串的长度以提高性能吗?

2 个答案:

答案 0 :(得分:3)

您可以使用maximum功能。 maximum还具有一个函数,在这种情况下,您可以使用该函数按a字段进行排序:

julia> struct myStruct
           a::Int
           b::Int
           c::String
       end

julia> myArray = myStruct.(21:30,11:20,"ABC");

julia> val = maximum(x -> x.a, myArray)
30

(对示例稍加修改,以使最大值和索引不同)。

答案 1 :(得分:2)

如{fredrikekre所述,获得a最大值的最简单方法是:

maxval = maximum(x->x.a, arr)

不幸的是,这并不能为您提供该值的索引,您也在注释中要求该值。

理想情况下,您可以改用argmaxfindmax

(maxval, maxind) = findmax(x->x.a, arr)  # <= This does not work!!

当前,在Julia的1.2版中,此方法无效。

可能还有其他一些聪明的解决方案,但是我的建议是自己编写一个循环,这很容易而且很有教育意义!

要解决您的问题:

0 :(这不是问题)请记住始终使用UpperCamelCase来命名您的类型:所以MyStruct,而不是myStruct

  1. 不,您不需要它,这不是一个好的解决方案。 (同样,当您仅查找a的最大值时,我也不知道为什么要使用2列向量)。但是,无论如何,如果您真的想要它:

    v = getproperty.(x, [:a :b])

  2. 有关最大值,请参见@fredrikekre的答案,有关最大索引,请参见下文。

  3. 不,我不这么认为。

编写自己的循环以获取最大索引和值。它既简单又有趣,您将学习编写自己的快速Julia代码:

function find_amax(arr::AbstractArray{MyStruct})
    isempty(arr) && ArgumentError("reducing over an empty collection is not allowed")
    maxind, maxval = firstindex(arr), first(arr).a
    for (i, x) in enumerate(arr)
        if x.a > maxval
            maxind, maxval = i, x.a
        end
    end
    return maxval, maxind
end

上面的代码效率很低,x的第一个值和索引被读取了两次。如果您想要更快的性能,可以找到一种避免这种情况的方法。

关于性能,此循环的速度大约是maximum(x->x.a, arr),并且是构建问题1中要求的2列矩阵的速度的60倍以上。

主要的教训是:您不需要寻找可以插入问题的聪明的“内置”解决方案。如果您无法快速找到一个,那就自己做一个,它很可能会更快