# Get value in nested data structure of arbitrary depth

**URL:** <https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 5, 2024, 7:34pm UTC](https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254 "2024-06-05T19:34:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [June 5, 2024, 7:34pm UTC](https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254/1 "2024-06-05T19:34:17Z")

</div>

Hi,

I would like to acess values of nested data structure with a `Tuple` representing the fields location in the data structure. The data structure can be of an arbitrary type and depth. Here is a MWE illustrating a few operations I would like to perform.

```julia
data = (a = 1, b = (a = [4,2], b = 3))
k1 = (:a,)
k2 = (:b, :a, 1)
function get_value(data, k)
    # get value at key k 
end
# returns 1
get_value(data, k1)
# returns 4
get_value(data, k2)

```

Is there a way to achieve this? Is recursion the right approach?

Thanks!

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [June 5, 2024, 8:10pm UTC](https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254/2 "2024-06-05T20:10:50Z")

</div>

A combination of dispatch and recursion would work:

```julia
get_value(data::NamedTuple, k::Symbol) = getproperty(data, k)
get_value(data::AbstractVector, k::Int) = getindex(data, k)
function get_value(data, k::Tuple)
    if length(k) == 0
        data
    else
        get_value(get_value(data, k[1]), k[2:end])
    end
end

```

Alternatively, you could just use a loop:

```julia
function get_value2(data, ks)
    for k in ks
        data = get(data, k, missing) # get works for many types and handles missing keys
    end
    data
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 5, 2024, 8:11pm UTC](https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254/3 "2024-06-05T20:11:29Z")

</div>

> [@Christopher\_Fisher](#):
>
> I would like to acess values of nested data structure with a `Tuple` representing the fields location in the data structure.

Can you give some context? What is the application, and how is the tuple of fields being generated?

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [June 5, 2024, 8:20pm UTC](https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254/4 "2024-06-05T20:20:44Z")

</div>

Thank you for your replies.

@bertschi, thank you. I think your second approach will work.

@stevengj, the context is a bit difficult to describe without going into a rabbit hole. Basically, I am trying to compare values in two data structures. I know the “keys” of each, but not the values at those keys.

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [June 5, 2024, 9:18pm UTC](https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254/5 "2024-06-05T21:18:46Z")

</div>

It’s not quite as bullet-proof as I had hoped for. A more rigorous solution might be using lenses from [Accessors.jl](https://github.com/JuliaObjects/Accessors.jl):

```julia-repl
julia> l1 = PropertyLens(:a) # describes path into data, i.e., like k1 = (:a,)
(@o _.a)

julia> l1(data)
1

julia> l2 = Accessors.opticcompose(PropertyLens(:b), PropertyLens(:a), IndexLens(1))
(@o _.b.a[1])

julia> l2(data)
4

```

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [June 5, 2024, 10:19pm UTC](https://discourse.julialang.org/t/get-value-in-nested-data-structure-of-arbitrary-depth/115254/6 "2024-06-05T22:19:56Z")

</div>

Thanks for the update! Accessors.jl looks like a relevant package.
