methods(+,(UnitRange{Int},Int))
# 0 methods for generic function "+" from Base
or is my local REPL broken?
This is what I had to add:
Base.:(+)(r::AbstractRange{T}, x::Real) where {T<:Real} = range(first(r)+x, step=step(r), length=length(r))
Also, why this does not work: Vect[[1,3,5,10:15]]? I had to create custom types to overload this behavior. Is there a performance reason to it? Why do I need to use vectors to retrive indexes instead of Tuples?
Nope, not broken; the lack of that method is highly intentional! But adding your own methods like that to + is indeed a very easy way to break your REPL
If you want to add a value to every value in an array, use broadcasting with .+.
Unlike some other languages, Julia draws a sharp distinction between an integer and an array of an integer. You can’t use them in the same places, nor can they seamlessly convert back-and-forth without manual intervention.
This is an intentional limitation that has a very significant payoff: in my experience the explicitness required — with either a broadcast . or something similar — ends up making code easier to read and less prone to unintentional errors.
It is never a good idea to put things with different types into the same vector. It usually leads to performance issues.
In your case, I propose to make all them ranges, i.e. replace say 5 with 5:5. Then the type is homogeneous. You can’t do a “double broadcast” easily but a list comprehension doesn’t seem too bad:
indices = [1:3, 5:5, 7:9]
shifted = [I .+ 2 for I in indices]
In this particular situation, I suggest vect[[1;3;5;10:12]]. There are more efficient possibilities and also probably some packages for doing this sort of thing, depending on your needs, but I would start with this.
You can offset these with vect[[1;3;5;10:12] .+ offset].
I agree on the fact that in this case tuple is better than vector. But since vect[1,3,5] and vect[(1,3,5)] does not work, but only vect[[1,3,5]], I wanted to stay consistent with that.
The solution you propose is interesting, but cumbersome. I wanted to provide an easy interactable framework, and that will complicate it even further
I didn’t know that with ; would work, but not with ,.
The difference that comes to mind is that one is a column-vector and the other is a row vector, is there something else under it? (just trying to understand)
also the correct one is vect[([1;3;5;10:12].+ offeset)] but don’t ask me why
[x;y;z] is equivalent to vcat(x,y,z) which is vertical concatenation. It creates a result with as many rows as there exist total in all the inputs. This works in this case because it takes all of your collections-of-Ints and makes them into one larger collection-of-Ints, which is a valid index type.
[x,y,z] is a different operation, which creates a 3-element array where one entry is each of the inputs. Julia doesn’t have definitions for how to index in this way (for good reason, as it quickly becomes very ambiguous) which is why it didn’t work for indexing nor offsetting.
Ohh, basically it works because it collects them. I wanted to keep them as unitrange for memory implications.
I think I’ll stick with what I got for the vector (basically I created a new type of vector which interact nicely with this type of things), and for the offset, if overloading the + for UnitRange is dangerous as @mbauman was saying, I will just implement an offset! function.