Array comparison

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]

thanks!

1 Like

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.

5 Likes

There’s probably a better way, but you can elementwise multiply the bit array, so

findall((a.>b) .* (a.<c))

will give you a bit array for all the indices of the elements you’re looking for. I think you actually want

a[findall((a.>b) .* (a.<c))]

to give the elements.

great!, still a lot to learn converting to Julia :slight_smile:

thanks

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

filter(x -> b<x<c, a)
2 Likes