How to select elements in array within range?

Hello,

I would like to know if there is a way to select elements in an array that fall between a range and assign them to a tuple.

test = sort(rand(10))

p_target = test[6]

I would like to select the elements of test that fall within 0.1 of p_target and assign them to s_target. How could this be done?

Here are a few ways:

test[abs.(test .- p_target) .< 0.1]

filter(t -> abs(t-p_target) < 0.1, test)
filter(t -> p_target - 0.1 < t < p_target + 0.1, test)
3 Likes

To add to the previous answer, if x is a vector then tuple(x...) will make it into a tuple.

Or (x...,)

Also

[x for x in test if -0.1<(x-p_target)<0.1]

Indeed. Also, Tuple(x) turns a vector into one, I miseed that part of the question. (Although it seems unlikely that a tuple is going to be the best choice here, but we’d have to know more.)

Thank you for your replies. I should clarify that I would like s_target or x to not include the value of p_target.

For those interested in the reason, I am trying to model by-catch, which I define as + and - a certain amount from the body size of the primary target (p_target). A different fishing ratio will be applied to s_target, so I cannot have the body weight of p_target included in s_target.

Could you please explain what the function of - is in test .- p_target or t-p_target? To me it looks like every element of test is subtracted by p_target, and if the result is less than 0.1, it is recorded. Is this correct? Sorry, my brain feels fuzzy at the moment.

Sure. If you print test .- p_target it has a zero in the 6th place, and small values nearby. If you print abs.(test .- p_target) .< 0.1 alone, it is mostly 0 (false) with some true near to the 6th. You could equally well use 0 .< abs.(test .- p_target) .< 0.1 if you want to exclude values precisely equal to p_target.

For the ones with filter, you can try replacing that with map, and will similarly get a vector of true/false, according to what the function t -> ... returns.

Using IntervalSets the code can be very elegant:

s_target = filter(x->x ∈ p_target ± 0.1 && x ≠ p_target, test)

:slight_smile:

1 Like

@improbable22 thank you for the explanation.

Sorry again. I realize I need the index number, like the 5 in test[5], not the value of what test[5] is. But I am glad for all the different ways everyone has shown - they will be handy to learn.

OK, then you may want findall, which takes a function and a collection just like filter, but returns the indices not the elements.

Thanks!