You can copy a NamedTuple with modifications using the merge function. Is there any similar facility for a unnamed Tuple, merging by index?
There is union
, but I don't know if it performs the kind on merge you want.
union
assumes a set, which is too strong an assumption for a Tuple.
You can do this:
a = (1, :b, 3)
Tuple((x = collect(a); x[3] = :c; x))
Just wondering if there was something more idiomatic.
Now I see what you mean. I don't know of any function in Base
to do this.
I think the difficulty is how to specify precedence; with named tuples, the last key "wins". An adhoc way to do it might be to write a merge
method such that merge( (1,2,3), (nothing, 10, nothing, 11) == (1, 10, 3, 11)
.
Do you want Base.setindex
?
I would, if it were defined for Tuple, but it is not.
it isn't?
It is only defined as Base.setindex! (note the !) as a mutation to an array. It is not defined for Tuple because they are not mutable. Perhaps Base.setindex (without a !) could be added to Julia for "setting" a value in an immutable via copy-with-modification?
julia> a = (1,2,3);
julia> b = Base.setindex(a,10,2);
julia> b
(1, 10, 3)
Nice :) Did it not get in the docs, or am I just not searching well?
I remember seeing something like that used in tupletools.jl, but I've also never seen it documented
There is a docstring though, so it probably is find-able in the documentation:
setindex(c::Tuple, v, i::Integer)
Creates a new tuple similar to x with the value at index i set to v. Throws a BoundsError when out of bounds.
Thank you for finding that.
no problem :)
It works on NamedTuple also.
There is also setindex!! from BangBang.jl
See TupleTools.jl
setindex(t,e,i)=(t[begin:i-1]..., e, t[i+1:end]...)
That'll be very slow
A better option would be something like
function setindex(t::Tuple{Vararg{Any, N}}, x, i) where {N}
ntuple(j -> i == j ? x : t[j], Val(N))
end
Ah, it appears that Base.setindex
already exists and works on Tuples. They have an equivalent implementation to the one I showed, but properly checked for bounds errors https://github.com/JuliaLang/julia/blob/master/base/tuple.jl#L52-L61
Yeah, that latter is what I tried, tii's also weirdly slow.
Hm, why is Base.setindex
not exported? It really annoys me how many seemingly useful things are not exported from Base
. If that's going to continue there really needs to be some way of knowing whether those methods are truly "private".
Expanding Man said:
Yeah, that latter is what I tried, tii's also weirdly slow.
tii's?
Mason Protter said:
That'll be very slow
But it's quick to write :grinning_face_with_smiling_eyes:
The fact that it is slow is understood by the structure of the function or have you checked it?
here a different proposal
function setindex_t2v(t,e,i)
arr=collect(t)
arr[i]=e
tuple(arr)
end
that one should allocate memory, while the compiler may be able to optimize allocations away for the original setindex
Last updated: Dec 28 2024 at 04:38 UTC