Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get values basis on keys from a Struct Elixir

Tags:

elixir

I have this value as

%{is_public: true, discoverable: true}

This could be anything not specifically is_public and discoverable, but all the keys which will come in above Map will be available in a struct of a camera.

%Camera{
  __meta__: #Ecto.Schema.Metadata<:loaded, "cameras">,
  created_at: #DateTime<2017-08-25 14:13:55.524563Z>,
  discoverable: true,
  exid: "everc-fhlcr",
  id: 12769,
  is_online: true,
  is_online_email_owner_notification: false,
  is_public: true,
  last_online_at: #DateTime<2019-05-14 11:10:45.000000Z>,
  last_polled_at: #DateTime<2019-05-14 11:10:47.000000Z>,
}

I want to get the values from the Camera struct on the basis of Map i.e

iex(4)> changes = %{is_public: true, discoverable: true} |> Map.keys
[:discoverable, :is_public]

I can get the keys from changes map with Map.keys

But I am not sure about how to map values from Camera struct.

from above Camera Struct and changes map, I want to get this type of Map.

%{
 is_public: true,
 discoverable: true
}

it seems like the same above map but it depends on Camera Struct values, they both can be false or true , same as id, exid, is_online.

If I do this

Enum.map(changed_keys, fn(key) ->
  key: Map.get(camera, key)
end)

This still doesn't work, any help would be appreciable. thanks

I just want to make a map with anonymous keys in changes Map, and then get their values from Camera Struct and create a new map with those values and anonymouse keys.

like image 918
Junaid Farooq Avatar asked Jun 25 '19 07:06

Junaid Farooq


2 Answers

The first task is to extract needed keys - it's already done perfectly with:

Map.keys(my_map)

Passing %{is_public: true, discoverable: true} as my_map make the deal:

iex> Map.keys(%{is_public: true, discoverable: true})
[:is_public, :discoverable]

Now, the question is - how to build one map from another, which will have only specified keys.

Fortunately, we have such a function in standard library: Map.take

We can use it like this:

Map.take(camera, [:discoverable, :is_public])

or (in particular case)

Map.take(camera, changes)

like image 146
Virviil Avatar answered Oct 02 '22 19:10

Virviil


FWIW, I’d post the solution that uses Kernel.SpecialForms.for/1 comprehension. Here it’s probably an ovekill, but in general it gives way more flexibility on filtering and any further processsing:

for {k, v} <- camera, k in [:discoverable, :is_public],
  do: {k, v}, into: %{}
#⇒ %{discoverable: true, is_public: true}
like image 41
Aleksei Matiushkin Avatar answered Oct 02 '22 19:10

Aleksei Matiushkin