# Best way to query the values of a struct with array of symbols

**URL:** https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259
**Category:** General Usage
**Created:** [February 6, 2020, 4:53pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259 "2020-02-06T16:53:22Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [February 6, 2020, 4:53pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/1 "2020-02-06T16:53:22Z")

</div>

I have an struct with some fields. Based on the types provided by the user at construction, I want the struct to remember certain fields of interest. I achieved this this way

```julia
mutable struct Foo{T}
    a::T
    b::T
    c::Array{T,1}
    fields::Array{Symbol,1}
end

```

For now, let’s assume that the interesting fields are always a and c.

```julia
function Foo(a,b,c)
    Foo(a,b,c,[:a,:c])
end

function get_interesting_fields(foo::Foo)
     reduce(vcat, [getfield(foo, f) for f in foo.fields])
end

```

What I want is to get a vector filled with a and the values in c. However this function is type unstable. Is there a better way to achieve this ?

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [February 6, 2020, 5:02pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/2 "2020-02-06T17:02:12Z")

</div>

I also would like to be able to change the value of the fields in the list. For example

```julia
function make_zeros(foo::Foo{T}) where T
    for f in foo.fields
       setfield!(foo, f, zero(T))
    end
end

```

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 6, 2020, 5:11pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/3 "2020-02-06T17:11:07Z")

</div>

`a` is a value of type `T`, `c` is a `Vector{T}`, a vector of values each of type `T`, you want to obtain a new vector `v = [a, c...]` that is  
`v = [a, c[1], c[2], .. c[end]]`.

```julia
function cull_info(x)
   return [x.a, x.c...]
end

myinfo = Foo(a,b,c)
v = cull_info(myinfo)

```

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [February 6, 2020, 5:16pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/4 "2020-02-06T17:16:49Z")

</div>

Oh yes I shoudl have specified, I must somehow iterate foo.fields because it may not always contain `:a` and `:c`.

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 6, 2020, 5:26pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/5 "2020-02-06T17:26:13Z")

</div>

Do you always know the names of the fields of interest at the time you want to cull information from them, or do you always know the index into the field sequence (1 for the field that appears first in the struct …)? Or do you mean use `a` and `c` when present otherwise use either if present otherwise `nothing`?

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [February 6, 2020, 5:34pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/6 "2020-02-06T17:34:36Z")

</div>

At construction, Foo checks the type of the arguments `a`, if it’s a `Union{Real, Vector{<:Real}}, `:a` is pushed to the Symbol list. Then it does the same for b and c. So I guess I always know the names of the fields, but implicitly I can derive the index too I suppose.

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 6, 2020, 6:01pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/7 "2020-02-06T18:01:23Z")

</div>

Is this correct?

```julia
#= 
a, b, and c are obtained
a, b, and/or c may or may not be a Real value or a vector of Real values
for each of a, b, c
   if it is of a type T <: Union{Real, Vector{Real}}
   then you want to save the field name as a symbol
 and that is how the value of your field `fields` is developed
---
  at some other processing
      you receive (are passed, or otherwise obtain)
      an previously valued realization of the struct type (an instance)
      and from that you wish to cull, as a single vector,
      all values that appear in the fields that are named as symbols in `fields`
           in order of those named symbols
---
=#

```

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [February 6, 2020, 6:27pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/8 "2020-02-06T18:27:59Z")

</div>

Yes

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 6, 2020, 6:44pm UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/9 "2020-02-06T18:44:05Z")

</div>

That we can do. 😉  
I am out for some hours now.  
Either when I return, or before then (by another person).

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 7, 2020, 2:55am UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/10 "2020-02-07T02:55:36Z")

</div>

```julia

#=
    TheStruct is the name of the structured type
        thestruct = TheStruct(args...)
        thestruct is the name of one realization of TheStruct
    
    with each realization of `TheStruct`
       the parameter `T1` becomes attached to a concrete type
          this is the type of the first field of TheStruct
       the parameter `T2` becomes attached to a concrete type
          this is the type of the second field of TheStruct
=#

struct TheStruct{T1, T2}
  a_field::T1
  b_field::T2
  fields_of_reals::Vector{Symbol}
end

const TheStruct_fieldnames = fieldnames(TheStruct)

#=
   The default constructor for TheStruct requires three arguments,
   which is clumsy. We specify a dispatching constructor:
=#
function TheStruct(args...)
  types_of_fields = typeof.(args)
  itr = zip(TheStruct_fieldnames, types_of_fields)
  real_fields = Symbol[]
  for (name,T) in itr
    if real_or_realvec(T)
      push!(real_fields, name)
    end
  end
  return TheStruct(args..., real_fields)
end

real_or_realvec(x) = eltype(x) <: Real

#= ~~~~~~~~~~~~ =#

a = 1618
b = [1.0, 2.0]
c = "c"

struct1 = TheStruct(a, b)
TheStruct{Int64,Array{Float64,1}}(1618, [1.0, 2.0], Symbol[:a_field, :b_field])

struct2 = TheStruct(a, c)
TheStruct{Int64,String}(1618, "c", Symbol[:a_field])

struct3 = TheStruct(c, a)
TheStruct{String,Int64}("c", 1618, Symbol[:b_field])

struct4 = TheStruct(c, c)
TheStruct{String,String}("c", "c", Symbol[])

```

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [February 7, 2020, 9:35am UTC](https://discourse.julialang.org/t/best-way-to-query-the-values-of-a-struct-with-array-of-symbols/34259/11 "2020-02-07T09:35:10Z")

</div>

This is why I really love Julia. Thank you so much !
