Questions of vector

julia> a=[(1,1),(1,2),(1,3),(1,4),(2,1),(2,2)]
6-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (1, 2)
 (1, 3)
 (1, 4)
 (2, 1)
 (2, 2)

There is a vector called a.If i input 1,I want to return [1,2,3.4].Also if I input 2,I want to return [1,2].Thanks for helping me.
And I also want to know the index of (1,4) in a.I wrote findfirst((x,y)->x==1&y==4,a),but it didn’t work.
Would you please to help me.Thanks.

findall(x -> first(x) == 1, a)

gives the desired indices

1 Like

If possible, it’s better to store this as a Dict: a = Dict(1 => [1, 2, 3, 4], 2 => [1, 2]). Of course, if the values are actually 1 and 2 (and similar consecutive small numbers), it’s even better to use arrays: a = [[1, 2, 3, 4], [1, 2]].

If you already have them as a vector of tuples for some other reason and would like to keep it so, you can do:

julia> getvalues(tuplearray, key) = last.(filter(t -> t[1] == key, tuplearray))
getvalues (generic function with 1 method)

julia> getvalues(a, 1)
4-element Vector{Int64}:
 1
 2
 3
 4

and

julia> findfirst(==((1, 4)), a)
4

(Note the double brackets on ==((1, 4)) - one pair for the function call ==(), another to define it as a tuple (1, 4).)

Thanks.If I want to know the index of (1,2) and (1,4),and return a vector. I can only think of one solution that I create a vector, and push it one by one like the following.

q=Int64[]
w=findfirst(==((1, 2)), a)
push!(q,w)
e=findfirst(==((1, 4)), a)
push!(q,e)

Is there a alternative way which is faster than this?I think push! is slow.

push! shouldn’t be that slow. Julia doesn’t allocate on every push! call.

Maybe you want findall?

julia> findall(a) do x
           x == (1, 1) ||
           x == (1, 4)
       end
2-element Vector{Int64}:
 1
 4
1 Like

I was going to suggest

julia> findall(in(((1, 4), (1, 2))), a)
2-element Vector{Int64}:
 2
 4

but @pdeffebach’s way is probably clearer.

If you’re going to be doing a lot of such find operations, then sorting your array and then using searchsorted would likely be even faster. In this example the array is already sorted, so:

julia> vcat((collect(searchsorted(a, t)) for t in ((1, 4), (1, 2)))...)
2-element Vector{Int64}:
 4
 2

(Though the code does get a bit messy like above due to the way searchsorted’s return value works.)

[quote=“pdeffebach, post:6, topic:87652”]
Maybe you want findall?
What I want to do is that I make a for loop,and push! it to the vector.And finally ,my aim is to delete them.I use deleteat!.I can delete one in each for.or delete at last.

a=[(1,1),(1,2),(1,3),(1,4),(2,1),(2,2)]
q=Int64[]
for m in a
    if isodd(m[1]+m[2])
        push!(q,findfirst(==((m[1], m[2])), a))
    end
end
julia> deleteat!(a,q)
3-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (1, 3)
 (2, 2)

or the next one

a=[(1,1),(1,2),(1,3),(1,4),(2,1),(2,2)]
for m in a
    if isodd(m[1]+m[2])
    deleteat!(a,findfirst(==((m[1], m[2])), a))
    end
end 

If I want to delete many , and i will push many times like the first code and finally delete.Or delete one by one.Are there any alternative ways like the first one in for loop but do not use push! to generate a vector.Thanks

You might be interested in SplitApplyCombine.jl for this kind of thing.

julia> filter!(a) do t
         !isodd(t[1] + t[2])
       end
3-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (1, 3)
 (2, 2)
a = [(1,1),(1,2),(1,3),(1,4),(2,1),(2,2)]
r = [element[2] for (indx, element) in pairs(a) if element[1] == 1]  # first question
a = [i for i in a if !isodd(i[1]+i[2])]  # last question