Reputation: 388
I'm doing a small Cli program with Ecto and when I do a query for some results I get a list and in the time that I've been learning Elixir something that I can't do right in the Terminal is to format the output of a function that returns a list.
When I run Repo.all(from u in Entry, select: u.title)
I get a list like this:
["test title", "second title"]
and I want to format that output to be like:
*****
test title
*****
second title
A division per item in the list but I don't know how to exactly do it or an efficent way of doing so. I've tried list comprehensions but well... it returns a list. Tried piping Enum.map/2
to IO.puts/1
with no result so now I require some help :-)
Upvotes: 2
Views: 1018
Reputation: 4517
You can try this
Repo.all(from u in Entry, select: u.title) |>
Enum.reduce([], fn item, acc ->
["********", item | acc]
end) |> Enum.reverse |> Enum.join("\n") |> IO.puts
Or a more reusable approach
iex(8)> display = fn list -> list |> Enum.reduce([], fn item, acc -> ["**********", item | acc] end) |> Enum.reverse |> Enum.join("\n") |> IO.puts end
#Function<6.54118792/1 in :erl_eval.expr/5>
iex(9)> ["test title", "second title"] |> display.() test title
**********
second title
**********
:ok
iex(10)> ~w(one two three four) |> display.()
one
**********
two
**********
three
**********
four
**********
:ok
iex(11)>
I often use the anoyn function approach in iex. can create little functions like that and reuse them without needing to define a module.
Here I added the display
function in to my .iex.exs
file. An ran it from a new iex session
Interactive Elixir (1.4.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> ~w(one two) |> display.()
one
**********
two
**********
:ok
iex(2)>
EDIT
If you wanted a real generic solution, you could override the inspect protocol in iex. However, this could affect your program if it uses inspect anywhere.
ex(7)> defimpl Inspect, for: List do
...(7)> def inspect(list, _opt \\ []), do: Enum.map_join(list, "\n", &(["*******\n", &1]))
...(7)> end
warning: redefining module Inspect.List (current version defined in memory)
iex:7
{:module, Inspect.List,
<<70, 79, 82, 49, 0, 0, 7, 184, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 242,
131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115,
95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...>>, {:__impl__, 1}}
iex(8)> ["Test one", "Test two"]
*******
Test one
*******
Test two
iex(9)>
Upvotes: 1
Reputation: 222358
I'd use Enum.map_join/3
:
iex(1)> ["test title", "second title"] |>
...(1)> Enum.map_join("\n", &["*****\n", &1]) |>
...(1)> IO.puts
*****
test title
*****
second title
Upvotes: 2