How to deal with structure elements?

I have the below MWE, in which at some points I need to check the field id of all elements of structure S (i.e., CP) before I continue add elements to CP, but I am having the below error. Any idea to solve it? In other words, why the command CP[:].id[1] returns an error, in my mind it should return the first position of field id of all elements in CP as matrix do.

mutable struct S
    id::Vector{String}
end
CP=S[];
push!(CP, S(["3d4f7006", "3d4f7006", "3d4f7006"]));
push!(CP, S(["3d5ce1ef", "3d5ce1ef", "3d5ce1ef"]));
p="3d4f7kkk";
if CP == [] || CP[:].id[1] .!= p
push!(CP, S([p, p, p]));
end
ERROR: type Array has no field id
Stacktrace:
 [1] getproperty(x::Vector{CP}, f::Symbol)
   @ Base .\Base.jl:33
 [2] top-level scope
   @ REPL[8]:1

You can do this:

julia> (x.id[1] for x in CP) .!= p
2-element BitVector:
 1
 1

still, note that the comparision will return a vector, such that the conditional there is probably not doing what you want.

1 Like

Perhaps you want this?

julia> if isempty(CP) || all(x -> x.id[1] != p, CP)
       push!(CP, S([p, p, p]));
       end
3-element Vector{S}:
 S(["3d4f7006", "3d4f7006", "3d4f7006"])
 S(["3d5ce1ef", "3d5ce1ef", "3d5ce1ef"])
 S(["3d4f7kkk", "3d4f7kkk", "3d4f7kkk"])
2 Likes

Uglier but certainly faster:

julia> function push_p!(CP,p)
           if isempty(CP)
               push!(CP,S([p,p,p]))
               return CP 
           end
           for s in CP
               s.id[1] == p && return CP
           end
           push!(CP,S([p,p,p]))
           return CP
       end
push_p! (generic function with 1 method)

julia> push_p!(CP,p)
3-element Vector{S}:
 S(["3d4f7006", "3d4f7006", "3d4f7006"])
 S(["3d5ce1ef", "3d5ce1ef", "3d5ce1ef"])
 S(["3d4f7kkk", "3d4f7kkk", "3d4f7kkk"])


1 Like

Interesting that this is faster, I would have expected these to be equivalent?

1 Like

Yeah, you’re right, at first sight I thought that all would apply the condition to all elements, but of course that is not the case. Probably using it is a good idea because of more careful handling of inbounds and stuff.

@jishnub @lmiq Thank you very much!

1 Like