Stream: helpdesk (published)

Topic: merge for Tuple?


view this post on Zulip Timothy Larson (Apr 13 2021 at 13:43):

You can copy a NamedTuple with modifications using the merge function. Is there any similar facility for a unnamed Tuple, merging by index?

view this post on Zulip mbaz (Apr 13 2021 at 13:47):

There is union, but I don't know if it performs the kind on merge you want.

view this post on Zulip Timothy Larson (Apr 13 2021 at 13:58):

union assumes a set, which is too strong an assumption for a Tuple.

view this post on Zulip Timothy Larson (Apr 13 2021 at 14:02):

You can do this:

a = (1, :b, 3)
Tuple((x = collect(a); x[3] = :c; x))

Just wondering if there was something more idiomatic.

view this post on Zulip mbaz (Apr 13 2021 at 14:18):

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).

view this post on Zulip Simeon Schaub (Apr 13 2021 at 17:05):

Do you want Base.setindex?

view this post on Zulip Timothy Larson (Apr 13 2021 at 17:20):

I would, if it were defined for Tuple, but it is not.

view this post on Zulip Maarten (Apr 13 2021 at 17:22):

it isn't?

view this post on Zulip Timothy Larson (Apr 13 2021 at 17:28):

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?

view this post on Zulip Maarten (Apr 13 2021 at 17:28):

julia> a = (1,2,3);

julia> b = Base.setindex(a,10,2);

julia> b
(1, 10, 3)

view this post on Zulip Timothy Larson (Apr 13 2021 at 17:31):

Nice :) Did it not get in the docs, or am I just not searching well?

view this post on Zulip Maarten (Apr 13 2021 at 17:32):

I remember seeing something like that used in tupletools.jl, but I've also never seen it documented

view this post on Zulip Maarten (Apr 13 2021 at 17:33):

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.

view this post on Zulip Timothy Larson (Apr 13 2021 at 17:34):

Thank you for finding that.

view this post on Zulip Maarten (Apr 13 2021 at 17:35):

no problem :)

view this post on Zulip Timothy Larson (Apr 13 2021 at 17:36):

It works on NamedTuple also.

view this post on Zulip Timothy Larson (Apr 13 2021 at 19:52):

There is also setindex!! from BangBang.jl

view this post on Zulip Jeffrey Sarnoff (Apr 15 2021 at 09:36):

See TupleTools.jl

view this post on Zulip rocco sprmnt21 (Aug 27 2021 at 17:15):

setindex(t,e,i)=(a[begin:i-1]..., e, a[i+1:end]...)

view this post on Zulip Mason Protter (Aug 27 2021 at 20:37):

That'll be very slow

view this post on Zulip Mason Protter (Aug 27 2021 at 20:50):

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

view this post on Zulip Mason Protter (Aug 27 2021 at 20:57):

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

view this post on Zulip Expanding Man (Aug 27 2021 at 21:16):

Yeah, that latter is what I tried, tii's also weirdly slow.

view this post on Zulip Expanding Man (Aug 27 2021 at 21:18):

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".

view this post on Zulip Mason Protter (Aug 27 2021 at 21:19):

Expanding Man said:

Yeah, that latter is what I tried, tii's also weirdly slow.

tii's?

view this post on Zulip rocco sprmnt21 (Aug 28 2021 at 06:26):

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

view this post on Zulip Maarten (Aug 28 2021 at 07:40):

that one should allocate memory, while the compiler may be able to optimize allocations away for the original setindex


Last updated: Oct 02 2023 at 04:34 UTC