# Unpack array of tuples and structs

**URL:** <https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188>\
**Category:** General Usage\
**Created:** [June 11, 2020, 8:54am UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188 "2020-06-11T08:54:33Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)\
**Post date:** [June 11, 2020, 8:54am UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/1 "2020-06-11T08:54:33Z")

</div>

Hello everyone,

I have a question which seems to be kind of related to [Convert array of tuples to vector](https://discourse.julialang.org/t/convert-array-of-tuples-to-vector/31603).

Edit : I just realized I can do these things with StructArrays except for the tuple case.  
However, I wonder if there is different way this can be done.

Let me give a MWE.

```julia
julia> struct Input
             a
             b
       end

julia> struct Output
             a
             b
       end

julia> function f1(inp :: Input, x)
           return x*inp.a, x*inp.b
       end 
f1 (generic function with 1 method)

julia> function f2(inp :: Input, x)
           return OutPut(x*inp.a, x*inp.b)
       end

julia> inp = Input(2.0,3.0)
Input(2.0, 3.0)

julia> f1(inp, 10)
(20.0, 30.0)

julia> f2(inp, 10)
OutPut(20.0, 30.0)

julia> v = 1:5
1:5

```

Now, if I input vector v to f1 I get

```julia
c =f1.(Ref(inp), v)
10-element Array{Tuple{Float64,Float64},1}:
 (2.0, 3.0)
 (4.0, 6.0)
 (6.0, 9.0)
 (8.0, 12.0)
 (10.0, 15.0)

```

**Question 1:**  
How can I get the the first, or second element of each tuple into a vector?

```julia
julia> c[:][1]
(2.0, 3.0)

```

which is not what I want.  
StructArrays does not seem to help here.It gives the same result.

Now, I can do the following:

```julia
julia> get_a(op :: Output) = op.a
get_a (generic function with 1 method)

julia> d =f2.(Ref(inp), v)
10-element Array{Output,1}:
 Output(2.0, 3.0)
 Output(4.0, 6.0)
 Output(6.0, 9.0)
 Output(8.0, 12.0)
 Output(10.0, 15.0)

julia> get_a.(d)
10-element Array{Float64,1}:
  2.0
  4.0
  6.0
  8.0
 10.0

```

This works great.  
I was wondering if there was another way to achieve something similar.  
I hoped that @unpack from Parameters.jl could do something like

```julia
julia> @unpack a, b .= d
ERROR: LoadError: Expression needs to be of form `a, b = c`
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] @unpack(::LineNumberNode, ::Module, ::Any) at /home/omerchiers/.julia/packages/Parameters/l76EM/src/Parameters.jl:743
in expression starting at none:1

```

but unfortunately it doesn’t work.

**Question 2:**  
Again, with StructArrays I can achieve my goal.  
But still I was wondering if there is some way to use @unpack like that?

Thanks in advance,  
Olivier

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [June 11, 2020, 11:05am UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/2 "2020-06-11T11:05:38Z")

</div>

> [@Olivier\_Merchiers](#):
>
> **Question 1:**  
> How can I get the the first, or second element of each tuple into a vector?

I love comprehensions (did I say that already?):

```julia
[x[1] for x in c ]
5-element Array{Float64,1}:
  2.0
  4.0
  6.0
  8.0
 10.0

```

---

<div class="post-metadata">

**Author:** ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)\
**Post date:** [June 11, 2020, 11:27am UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/3 "2020-06-11T11:27:45Z")

</div>

that’s great!  
thanks a lot

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [June 11, 2020, 12:11pm UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/4 "2020-06-11T12:11:05Z")

</div>

Arguably the more idiomatic solution here is `first.(c)` and `last.(c)`, more generally you can broadcast `getindex` like `getindex.(c, 1)`

---

<div class="post-metadata">

**Author:** ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)\
**Post date:** [June 11, 2020, 12:29pm UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/5 "2020-06-11T12:29:01Z")

</div>

**EDIT** : I totally missed the point. I delete the post.

---

<div class="post-metadata">

**Author:** ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)\
**Post date:** [June 11, 2020, 1:36pm UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/6 "2020-06-11T13:36:04Z")

</div>

Thanks for the suggestion.

The Input struct was probably not really necessary in my MWE.  
I just wanted to show two functions: one that outputs a tuple and another one that outputs some struct.  
And how to handle these two cases when outputting a vector of those.

But thanks anyway.

---

<div class="post-metadata">

**Author:** ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)\
**Post date:** [June 11, 2020, 1:49pm UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/7 "2020-06-11T13:49:22Z")

</div>

ooh that’s also very cool.  
but now this makes me wonder why the following things work as expected

- getindex.(c,1)
- c[1][1]
- c[:]

but this

- c[:][1]

does not

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [June 11, 2020, 1:57pm UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/8 "2020-06-11T13:57:51Z")

</div>

> [@Olivier\_Merchiers](#):
>
> c[:][1]

That’s equivalent to:

```julia
temp = c[:]
temp[1]

```

Try running those two lines and look at what `temp` ends up as.

In other words, the expression `c[:][1]` creates a copy of `c` and then takes the first element of that copy. It’s a valid thing to do, but not a very useful one.

---

<div class="post-metadata">

**Author:** ![Olivier\_Merchiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivier_merchiers/32/4073_2.png) [@Olivier\_Merchiers](https://discourse.julialang.org/u/Olivier_Merchiers)\
**Post date:** [June 11, 2020, 2:26pm UTC](https://discourse.julialang.org/t/unpack-array-of-tuples-and-structs/41188/9 "2020-06-11T14:26:57Z")

</div>

yes indeed, now it makes sense.

```julia
julia> c == c[:]
true

```

hence

```julia
julia> c[1] == c[:][1]
true

```

Totally logical, but somehow I find it disturbing.  
Thanks a lot for this very insightful example.
