# Non allocating tuple transformations which include index

**URL:** <https://discourse.julialang.org/t/non-allocating-tuple-transformations-which-include-index/58599>\
**Category:** General Usage\
**Tags:** tuple\
**Created:** [April 5, 2021, 8:36am UTC](https://discourse.julialang.org/t/non-allocating-tuple-transformations-which-include-index/58599 "2021-04-05T08:36:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 5, 2021, 8:36am UTC](https://discourse.julialang.org/t/non-allocating-tuple-transformations-which-include-index/58599/1 "2021-04-05T08:36:14Z")

</div>

When one is working with tuples, what is the idiomatic way to do operations, when it is necessary to use element indices?

For example, consider that there is a tuple

```julia
t = (0.1, 0.2, 0.3, 0.4)

```

and it should be transformed as `t[i] -> i * t[i]^2`. More or less obvious solutions are not working, since

```julia
map(x -> x[1]*x[2]^2, pairs(t))

```

throws an error `ERROR: map is not defined on dictionaries` and

```julia
map(x -> x[1]*x[2]^2, enumerate(t))

```

works fine, but it returns `Vector` instead of tuple and so it allocates.

Another example is

```julia
t1 = (0.1, 0.2, 0.3, 0.4)
t2 = (0.1, 0.1, 0.5, 0.5)

```

and I need to map it to a tuple of tuples, i.e. `((0.1, 0.1), (0.2, 0.1), (0.3, 0.5), (0.4, 0.5))`.

```julia
map(identity, zip(t1, t2))

```

and the like are allocating for the same reason as they do in `enumerate` case.

I did something like

```julia
function indexmap(f, t, i = 1)
    length(t) == 1 && return (f(first(t), i), )
    (f(first(t), I), indexmap(f, Base.tail(t), i + 1)...)
end

```

but it looks hackish to me and I think that I am missing something obvious.

---

<div class="post-metadata">

**Author:** ![maxfreu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxfreu/32/17468_2.png) [@maxfreu](https://discourse.julialang.org/u/maxfreu)\
**Post date:** [April 5, 2021, 9:28am UTC](https://discourse.julialang.org/t/non-allocating-tuple-transformations-which-include-index/58599/2 "2021-04-05T09:28:42Z")

</div>

Maybe look at [ntuple](https://docs.julialang.org/en/v1/base/base/#Base.ntuple) (Sorry for being brief, am on phone)

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 5, 2021, 9:37am UTC](https://discourse.julialang.org/t/non-allocating-tuple-transformations-which-include-index/58599/3 "2021-04-05T09:37:17Z")

</div>

Sure, you are right! I knew that it was going to be something obvious.

---

<div class="post-metadata">

**Author:** ![maxfreu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxfreu/32/17468_2.png) [@maxfreu](https://discourse.julialang.org/u/maxfreu)\
**Post date:** [April 5, 2021, 10:00am UTC](https://discourse.julialang.org/t/non-allocating-tuple-transformations-which-include-index/58599/4 "2021-04-05T10:00:36Z")

</div>

Happy easter 🙂

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 5, 2021, 10:11am UTC](https://discourse.julialang.org/t/non-allocating-tuple-transformations-which-include-index/58599/5 "2021-04-05T10:11:08Z")

</div>

In case someone is interested in implementation details, first question can be solved with

```julia
ntuple(i -> i * t[i]^2, length(t))

```

and second is

```julia
ntuple(i -> (t1[i], t2[i]), length(t1))

```

Of course, it’s a user responsibility to validate that `length(t1) == length(t2)`.
