Replace Vector at indices and return a copy

What’s the easiest way to return a copy of a Vector with replaced elements at some indices with some specific values ?
I can start with one approach:

julia> v = [10,20,30,40,50];

julia> inds = [2,5];

julia> vals = [200, 500];

julia> newv = let v2=deepcopy(v); v2[inds] = vals; v2; end
5-element Vector{Int64}:
  10
 200
  30
  40
 500

julia> v #still hasn't changed
5-element Vector{Int64}:
 10
 20
 30
 40
 50

I was expecting that there would be a replaceat and replaceat! function to do this.
The implementation would be maybe something similar along the way:

function replaceat(v, inds, vals)
  v2 = deepcopy(v)
  v2[inds] = vals
  v2
end

function replaceat!(v, inds, vals)
  v[inds] = vals
  v
end
v[inds].=vals

in place replacement

for a copy

v[inds]=vals

Why would you need a replaceat function, when the current solution is even simpler:

v[inds] = vals

?

Also, I would use copy.

No, those two are the same, both are in-place.

I probably meant not allocating vs allocating :flushed:

They are actually indistinguishable. There’s no observable difference between them, it’s just that the dotted version involves broadcasting, but in the end it amounts to the same thing.

1 Like

This is what Accessors.jl is for.

using Accessors

julia> x = [10,20,30]
3-element Vector{Int64}:
 10
 20
 30

julia> @set x[2] = 99
3-element Vector{Int64}:
 10
 99
 30

julia> x
3-element Vector{Int64}:
 10
 20
 30
1 Like

Both expressions are not what I need.
Probably my bad.
The original v vector must not be mutated.
So first make a copy and then mutate the copy.
Have a look at my working example.

Plus v[inds]=vals return vals which is bad for one-liners. I would like it to return the mutated copy of v.

I think the scenarios could be quite a few.
I just have an original vector and I want get another one with just some replaced values based on index.
There is replace and replace! but these work in the value level.

Yes, this was clear. You were requesting both an in-place and an out-of-place version, so it was implied that you had to copy for the out-of-place version.

Then it seems like Accessors.@set is the way to go, or making your own.

that’s it. Also works for multiple replacements with @set v[inds] = vals .
perfect!