hauks96

hauks96

Building map from list of columns and list of values

I’m trying to implement an efficient generic function to map the results from a Postgrex call into a map. Any suggestions?

  • Example result from postgrex:
%Postgrex.Result{
   columns: ["first_column", "second_column"],
   command: :select,
   num_rows: 4,
   rows: [["a", 1], ["b", 2], ["c", 3], ["d", 4]]
 }
  • Desired output
[
%{first_column: "a", second_column: 1},
%{first_column, "b", second_column: 2},
%{first_column, "c", second_column: 3},
%{first_column, "d", second_column: 4}
]

Marked As Solved

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

No worries about being a noob, but as a general note for future questions it’s also best to show the code that you’ve tried so that we can help you learn.

The most succinct way to do this is with Enum.zip. Assuming you have the struct you listed as a result variable you can do:

Enum.map(result.rows, fn row ->
  result.columns
  |> Enum.zip(row)
  |> Map.new()
end)

Also Liked

Sebb

Sebb

I can only second that. To cleanse yourself from the sins of the imperative world you should reimplement the Enum functions. This is one of the exercises in the Exercism Elixir Track. This is very much recommended! Reimplmenting Enum is not easy, so there are a lot of very good execises to lead you there.

Sebb

Sebb

You do not need to index the lists. They already fit together.

iex(1)> Enum.zip(["first_column", "second_column"], ["a", 1])
[{"first_column", "a"}, {"second_column", 1}]
benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

I’d highly recommend starting with a simpler question and seeing if you can build it from scratch without Enum, it’ll help with those for i cobwebs. Given:

columns = ["first_column", "second_column"]
values = ["a", 1]

How would you build a function that returned:

[{["first_column", "a"}, {"second_column", 1}]

without using Enum or List or anything like that? (Hint, recursion!)

Sebb

Sebb

What have you tried?

Eiji

Eiji

Here are 2 examples:

defmodule Example do
  def sample1(%Postgrex.Result{columns: columns, rows: rows}) do
    Enum.map(rows, fn row ->
      Enum.zip_reduce(columns, row, %{}, &Map.put(&3, String.to_atom(&1), &2))
    end)
  end

  def sample2(%Postgrex.Result{columns: _columns, rows: []}), do: []

  def sample2(%Postgrex.Result{columns: columns, rows: [row | rows]}) do
    [sample2(columns, row, %{}) | sample2(%Postgrex.Result{columns: columns, rows: rows})]
  end

  defp sample2([], [], acc), do: acc

  defp sample2([column | columns], [value | row], acc) do
    acc = Map.put(acc, String.to_atom(column), value)
    sample2(columns, row, acc)
  end
end

The first example is really short as it uses a helper Enum functions. On the other hand the second example uses just a simple pattern-matching.

Helpful resources:

  1. Enum.map/2
  2. Enum.zip_reduce/4
  3. Map.put/3
  4. String.to_atom/3
  5. Kernel.SpecialForms.&/1 (Capture operator)
  6. Patterns and Guards

Please keep in mind below every time you want to convert String to Atom:

Warning: this function creates atoms dynamically and atoms are not garbage-collected. Therefore, string should not be an untrusted value, such as input received from a socket or during a web request. Consider using to_existing_atom/1 instead.

Source: String.to_atom/3 — Elixir documentation

Where Next?

Popular in Questions Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement