Enum intersperse
Intersperse is the action of putting something in between other things.
We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
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.
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.
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>