In your Elixir application you might find yourself needing to output a string of comma separated names. You could do something like this as your first attempt but, this approach creates an extra comma and white space.
# Step 1
users = ["tony", "sam", "alex"]
# Step 2 - Add a comma to each name
list = for user <- users do
"#{user}" <> ", "
end
# Step 3 - Joinh into a string
Enum.join(list, "")
# "tony, sam, alex, "
What you want is the comma to appear in between the names. This is whereEnum.interprese/2
can help out.
# Step 1
users = ["tony", "sam", "alex"]
# ["tony", "sam", "alex"]
# Step 2 - Look at the commas within the list
list = Enum.intersperse(users, ", ")
# ["tony", ", ", "sam", ", ", "alex"]
# Step 3 - Join into a string
Enum.join(list, "")
# "tony, sam, alex"
This approach is much better. By using Enum.interprese/2
and Enum.join/2
you can achieve the result you were looking for.
However, our application is interactive and we need to get these names clickable. Let’s see how we can do this in a Phoenix application.
Real World Example
In my Phoenix application I have a list of users that need to be separated by a comma. Each user needs to be clickable but the comma needs to be plain text. In order to do this we are going to create a helper.
Create a shared_view.ex
file within the views
directory. This module is going to contain common functions that will be used across the application.
defmodule DemoWeb.SharedView do
use DemoWeb, :view
def linked_users(conn, users) do
users
|> Enum.map(fn(users) ->
link(users.name, to: user_path(conn, :show, user.name), title: "See #{user.name} content")
end)
|> Enum.intersperse(", ")
end
end
With DemoWeb.SharedView.linked_users/2
you pass in the current conn
and the users
. The function will then map through each user in the users
list and apply the link/2
function to each user.
Once the map function has gone through the list, it returns a List containing HTML links. This list will then be passed into the Enum.interprese/2
as the first argument thanks to the |>
and we pass in the ", "
as the second argument. The result is we get an HTML presentation of links being separated by a comma.
Using the shared view
In my templates/shared
directory I will use this as a template to render the list of users
<%= linked_users(@conn, @users) %>
In my Phoenix web app, I have a home page that shows some @users
. So, I can now render
the DemoWeb.SharedView
module by calling that users.html
and passing in the arguments as shown below
<section>
<div class="container user-listing">
<%= render DemoWeb.SharedView, "users.html", conn: @conn, users: @users %>
</div>
</section>
Then my application should output HTML that looks something like this
<section>
<div class="container user-listing">
<p>
<a href="/user/tony" title="See tony content">tony</a>,
<a href="/user/sam" title="See sam content">sam</a>,
<a href="/user/alex" title="See alex content">alex</a>
</p>
</div>
</section>