<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>recursion Archives | Programming Zen</title>
	<atom:link href="https://programmingzen.com/tag/recursion/feed/" rel="self" type="application/rss+xml" />
	<link>https://programmingzen.com/tag/recursion/</link>
	<description>Meditations on programming, startups, and technology</description>
	<lastBuildDate>Sat, 09 May 2020 04:08:22 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
<site xmlns="com-wordpress:feed-additions:1">1397766</site>	<item>
		<title>Removing Duplicates From a List in Elixir</title>
		<link>https://programmingzen.com/remove-duplicates-from-list-elixir/</link>
					<comments>https://programmingzen.com/remove-duplicates-from-list-elixir/#comments</comments>
		
		<dc:creator><![CDATA[Antonio Cangiano]]></dc:creator>
		<pubDate>Thu, 07 May 2020 04:27:39 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[elixir]]></category>
		<category><![CDATA[elixir-cookbook]]></category>
		<category><![CDATA[Enum]]></category>
		<category><![CDATA[List]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[tips]]></category>
		<guid isPermaLink="false">https://programmingzen.com/?p=2486</guid>

					<description><![CDATA[<p>Thanks to the Enum module, in Elixir we can trivially remove duplicates from a list. In the following example, we take a list of integers and pass it to the Enum.uniq/1 function which removes duplicates from the list without altering the original order of the remaining elements. If you are trying to only remove consecutive duplicate elements, then there is Enum.dedup/1: (Note: We append /1 simply as a notation indicating the arity of a function, that is how many arguments it accepts. my_func/1 accepts one argument, my_func/2 two, and so on.) Enum is full of helpful functions when working with </p>
<p>The post <a href="https://programmingzen.com/remove-duplicates-from-list-elixir/">Removing Duplicates From a List in Elixir</a> appeared first on <a href="https://programmingzen.com">Programming Zen</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Thanks to the <code>Enum</code> module, in Elixir we can trivially remove duplicates from a list.</p>



<p>In the following example, we take a list of integers and pass it to the <code>Enum.uniq/1</code> function which removes duplicates from the list without altering the original order of the remaining elements.</p>



<pre class="wp-block-code"><code>list = &#91;1, 2, 2, 3, 3, 1, 2, 4]
Enum.uniq(list) # Returns &#91;1, 2, 3, 4]</code></pre>



<p>If you are trying to only remove consecutive duplicate elements, then there is <code>Enum.dedup/1</code>:</p>



<pre class="wp-block-code"><code>list = &#91;1, 2, 2, 3, 3, 1, 2, 4]
Enum.dedup(list) # Returns &#91;1, 2, 3, 1, 2, 4]</code></pre>



<p>(Note: We append <code>/1</code> simply as a notation indicating the <em>arity</em> of a function, that is how many arguments it accepts. <code>my_func/1</code> accepts one argument, <code>my_func/2</code> two, and so on.)</p>



<p><a rel="noreferrer noopener" href="https://hexdocs.pm/elixir/Enum.html" target="_blank">Enum is full of helpful functions</a> when working with collection data types that implement the <code>Enumerable</code> protocol (e.g., lists, maps, ranges, streams, etc.) and it&#8217;s worth getting acquainted with.</p>



<h2 class="wp-block-heading">Removing duplicates using recursion</h2>



<p>Alright, Elixir does the heavy lifting for us in this case, but how would we go about removing duplicates from a list in Elixir without using <code>Enum.uniq/1</code>? I mean from scratch, simply using recursion without relying on <code>Enum</code>, sets, <code>:lists.usort/1</code>, etc. </p>



<p>It is worth asking such a question to both exercise our recursion muscle (something that doesn&#8217;t come naturally to most programmers) and so that we&#8217;re ready to handle conceptually similar problems that do not have pre-made functions but could benefit from a recursive solution.</p>



<p>There are likely a few ways to implement this, but this what sprang to mind when I thought about it:</p>



<pre class="wp-block-code"><code>defmodule MyList do
  def uniq(&#91;]), do: &#91;]

  def uniq(&#91;head | tail]) do
    &#91;head | for(x &lt;- uniq(tail), x != head, do: x)]
  end
end</code></pre>



<p>Calling <code>MyList.uniq(list)</code> will then return the same list without duplicates as <code>Enum.uniq(list)</code>did. (Although, it&#8217;s worth noting, that we implemented a <code>List</code>-specific version of the <code>uniq/1</code> function).</p>



<p>Let&#8217;s see how this works. If the list is empty (i.e., <code>[]</code>) we obviously return an empty list, as there is nothing to remove. This is our base case for the recursion.</p>



<p>If the list is not empty, it will have a head and a tail, and we use Elixir&#8217;s pattern matching to bind the first element of the list passed to the function to <code>head</code> and the rest of the elements to the list <code>tail</code>. </p>



<p>Note that a proper list with a single element will simply have an empty list as its tail. So writing <code>[3]</code> is equivalent to writing <code>[3|[]]</code> where <code>3</code> is the head, <code>[]</code> is the tail, and <code>|</code> is the cons operator (short for constructor operator, as it&#8217;s used to construct lists).</p>



<p>So far so good. Here is where things get a little trickier. Let&#8217;s analyze this line:</p>



<pre class="wp-block-code"><code>    &#91;head | for(x &lt;- uniq(tail), x != head, do: x)]</code></pre>



<p>The code is wrapped in square brackets <code>[...]</code>which means that we are returning a list. Then you&#8217;ll notice the <code>|</code> <em>cons</em> operator. So we are constructing a list that has <code>head</code> as its first element and whatever the rest of that line of code does, as its tail.</p>



<p>This makes sense if you think about it. Sure, the list might have duplicates, but the first element will always be included. If a duplicate of the first element exists, that&#8217;s the one that is going to be removed and not the first element.</p>



<p>So we are building a list and the first element of the original list is also the first element of our deduplicated list. What goes into the rest of the list?</p>



<h3 class="wp-block-heading">Comprehensions</h3>



<p>We see a <code>for</code>. Unlike many programming languages, <code>for</code> is not a loop keyword in Elixir. Rather, it is used for comprehensions (a form of syntax sugar to generate lists from existing collections). Syntax, which is not too different from mathematical notation.</p>



<p>Here is a simple example of how to use them:</p>



<pre class="wp-block-code"><code>for x &lt;- &#91;1, 2, 3, 4], do: x + x # Returns &#91;2, 4, 6, 8]</code></pre>



<p>&#8220;For each element <code>x</code> in <code>[1, 2, 3, 4]</code> do <code>x + x</code> and put the result in a list.&#8221;</p>



<p>It also accepts filters, which allows us to specify a condition:</p>



<pre class="wp-block-code"><code>for x &lt;- &#91;1, 2, 3, 4], x &lt; 3, do: x + x # Returns &#91;2, 4]</code></pre>



<p>In this example, the condition is that <code>x</code> is smaller than <code>3</code>, so only the first two elements, which are lesser than <code>3</code>, get doubled and added to the resulting list.</p>



<h3 class="wp-block-heading">Recursing our way to the base case</h3>



<p>OK, back to our &#8220;cryptic&#8221; line:</p>



<pre class="wp-block-code"><code>    &#91;head | for(x &lt;- uniq(tail), x != head, do: x)]</code></pre>



<p><code>head</code> is our first element and then we are using a comprehension to generate a list without duplicates.</p>



<p>We are saying, for each <code>x</code> in a deduplicated <code>tail</code>, add <code>x</code> to the list if it&#8217;s different from our first element <code>head</code>.</p>



<p>The part that gets people weirded out about is recursively calling <code>uniq(tail)</code>. We can get away with this because we have a base case that ensures we don&#8217;t recurse forever.  </p>



<p>At each call of <code>uniq(tail)</code> we are making the tail shorter by one element. </p>



<p>For example, executing <code>MyList.uniq([1, 2, 3, 3])</code> will make the following recursive calls:</p>



<ul class="wp-block-list"><li><code>MyList.uniq([1, 2, 3, 3])</code></li><li><code>MyList.uniq([2, 3, 3])</code></li><li><code>MyList.uniq([3, 3])</code></li><li><code>MyList.uniq([3])</code></li><li><code>MyList.uniq([])</code></li></ul>



<p>When we eventually get to the tail being <code>[]</code>, which is our base case,<code>[]</code> is returned and <code>MyList.uniq/1</code> is no longer called.</p>



<p>Recursion can be hard to grasp at first, but it&#8217;s a powerful tool and a staple of functional programming, so it&#8217;s well worth practicing.</p>



<p>As pointed out in the comment section, this implementation is quite illustrative but not very efficient. In production, you&#8217;d want to opt for the built-in functions or implement a tail-recursive version that leverages <code><a rel="noreferrer noopener" href="https://hexdocs.pm/elixir/MapSet.html" target="_blank">MapSet</a></code>. And although tail recursion is faster in this case, it&#8217;s worth noting that even that is <a href="http://erlang.org/doc/efficiency_guide/myths.html" target="_blank" rel="noreferrer noopener">not a silver bullet</a>.</p>
<p>The post <a href="https://programmingzen.com/remove-duplicates-from-list-elixir/">Removing Duplicates From a List in Elixir</a> appeared first on <a href="https://programmingzen.com">Programming Zen</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programmingzen.com/remove-duplicates-from-list-elixir/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2486</post-id>	</item>
	</channel>
</rss>
