# Is a Structure in a Collection

I want to find whether a Structure of Type A is in included in A Collection. In the next step I wanna return this collection form a Collection of a Collection of Type A^^.

``````struct A
a = Int
end

a = [A(1), A(2)]
in(a, A(1))
``````

This throws the Error:

``````ERROR: MethodError: no method matching iterate(::A)
Closest candidates are:
iterate(::Union{LinRange, StepRangeLen}) at ~/packages/julias/julia-1.7/share/julia/base/range.jl:826
iterate(::Union{LinRange, StepRangeLen}, ::Integer) at ~/packages/julias/julia-1.7/share/julia/base/range.jl:826
iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}} at ~/packages/julias/julia-1.7/share/julia/base/dict.jl:695
...
Stacktrace:
[1] in(x::Vector{A}, itr::A)
@ Base ./operators.jl:1282
[2] top-level scope
@ REPL[6]:1

``````

I assume I have to implement an iterate function?! How is this done? What needs to be returned?

First things first:

``````julia> struct A
a::Int
end

julia> a = [A(1), A(2)]
2-element Vector{A}:
A(1)
A(2)

julia> findfirst(x->x==A(1),a)
1

julia> in(A(1),a)
true
``````
2 Likes

Let us see what this is.

Seems that your question is answered, but this is another interpretation for that question:

``````julia> struct A a::Int end;

julia> struct B b::Int end;

julia> a = [ B(1), A(2) ]
2-element Vector{Any}:
B(1)
A(2)

julia> findfirst(x -> isa(x,A), a)
2

``````

And then maybe the second question is:

``````julia> a = [ A(1), B(1), A(2) ]
3-element Vector{Any}:
A(1)
B(1)
A(2)

julia> findall(x -> isa(x,A), a)
2-element Vector{Int64}:
1
3

julia> a2 = a[findall(x -> isa(x,A), a)]
2-element Vector{Any}:
A(1)
A(2)

``````
1 Like

Sorry, my desciption must have been not so clear. What I wanted to do is something similar to:

``````
julia> struct Point{t<:Real}
row:: t
col:: t
end

a = [Point(1, 1), Point(2, 2)]
b = [Point(1, 2), Point(2, 1)]
ab = [a, b]
ab[findfirst(x-> in(x, Point(1, 1), ab)]
``````

From the error message I assume that the in function, applies an iteratertion which is not implemented for this Type â€śPointâ€ť.

for function `in` its:

``````in(item, collection)
``````

you use it the other way round.

3 Likes

thanks @oheil

One step at the time: First, the `in` call is inverted, this works,

``````julia> a = [Point(1, 1), Point(2, 2)]
2-element Vector{Point{Int64}}:
Point{Int64}(1, 1)
Point{Int64}(2, 2)

julia> findfirst(x -> in(Point(1,1), a), a)
1

# and (more reasonably in this case):
julia> findfirst(x -> x==Point(1,1), a)
1

#or (I like this one)
julia> findfirst(isequal(Point(1,1)), a)
1

``````

Now, you have a collection of collections. This command (with the dot: `findall.()`, will apply the `findall` operation to each element of the â€śouterâ€ť collection (this is the standard broadcast syntax of Julia):

``````julia> a = [Point(1, 1), Point(2, 2)];

julia> b = [Point(1, 2), Point(2, 1), Point(1,1) ];

julia> ab = [a, b];

julia> findall.(isequal(Point(1,1)), ab)
2-element Vector{Vector{Int64}}:
[1]
[3]
``````

Which is an array of vectors, containing the desired indexes of the elements at for each vector. It that is not what you want, you can use, for example:

``````julia> filter(isequal(Point(1,1)), reduce(vcat, ab))
2-element Vector{Point{Int64}}:
Point{Int64}(1, 1)
Point{Int64}(1, 1)
``````

(where `reduce(vcat, ab)` flattens the `ab` array of arrays into a simple vector:

``````julia> reduce(vcat, ab)
5-element Vector{Point{Int64}}:
Point{Int64}(1, 1)
Point{Int64}(2, 2)
Point{Int64}(1, 2)
Point{Int64}(2, 1)
Point{Int64}(1, 1)

``````
2 Likes