Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get_in for nested list & struct in elixir

Tags:

elixir

I have a structure

s = [
  a: %Bla{
   b: "c"
  }
]

I want to take c value from it. I'm trying to do

get_in(s, [:a, :b])

But it's not designed to take value from the struct. Is there any analogue which allows me to fetch c from the list with nested struct?

like image 419
asiniy Avatar asked Oct 04 '16 14:10

asiniy


2 Answers

As documented, get_in does not work with structs by default:

The Access syntax (foo[bar]) cannot be used to access fields in structs, since structs do not implement the Access behaviour by default. It is also design decision: the dynamic access lookup is meant to be used for dynamic key-value structures, like maps and keywords, and not by static ones like structs.

There are two ways to achieve what you want:

  1. Implement Access behaviour for your struct.

  2. Use Access.key(:foo) instead of :foo.

I would use (2):

iex(1)> defmodule Bla do
...(1)>   defstruct [:b]
...(1)> end
iex(2)> s = [a: %Bla{b: "c"}]
[a: %Bla{b: "c"}]
iex(3)> get_in(s, [:a, Access.key(:b)])
"c"
like image 144
Dogbert Avatar answered Oct 20 '22 05:10

Dogbert


Here is my version of try function to return values from both maps and structs:

def try(map, keys) do
  Enum.reduce(keys, map, fn key, acc -> 
    if acc, do: Map.get(acc, key) 
  end)
end
like image 43
denis.peplin Avatar answered Oct 20 '22 03:10

denis.peplin