This seems like a very newby question, since I’m trying to do something very simple.
I want to find the array elements between two values. I can make it work with my third attempt in the code, but it feels like there is a much more elegant way … .
a=collect(1:30)
b=10
c=20
# attempt 1
findall(a.>b && a.<c) #does not work since bit arrays and boolean operations can't be combined
# attempt 2
comp1=convert(Array{Bool},a.>b)
comp2=convert(Array{Bool},a.<c)
findall(comp1 && comp2) # does not work
findall(comp1. && comp2) # does not work
# attempt 3
idx=findall(a.>b)
idx2=findall(a[idx].<c)
a[idx][idx2]
You can broadcast & but not &&, but mind the brackets else you get bitwise & of the integers. But you can also write two comparisons at once, b < a < c:
julia> a,b,c = 0:2:50, 10, 20; # no need to collect
julia> findall(b .< a .< c) # indices
4-element Array{Int64,1}:
7
8
9
10
julia> a[@. (a>b) & (a<c)] # or a[ans], values
4-element Array{Int64,1}:
12
14
16
18
julia> (a .> b .& a .< c) == (a .> (b .& a) .< c) # bitwise on Int
true
You could also write filter(x -> b<x<c, a) for the values, or findall(i -> b<a[i]<c, eachindex(a)) for the indices.
Just a note - the function findall returns indices of elements that are true when only given an iterable, or indices of element for which a first-argument function returns true when given a function and then an iterable. If you want the elements themselves, use the filter function, optionally with a ! if you want to mutate the iterable (a in the original post) that is passed. filter takes a function and then an iterable. The way I would do this is