<!DOCTYPE html> <html> <head> <meta http-eqiv="content-type" content="text/html;charset=utf-8"> <title>Go by Example: Sorting by Functions</title> <link rel=stylesheet href="site.css"> </head> <script type="text/javascript"> if (window.location.host == "gobyexample.com") { var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-34996217-1']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); } </script> <body> <div class="example" id="sorting-by-functions"> <h2><a href="./">Go by Example</a>: Sorting by Functions</h2> <table> <tr> <td class="docs"> <p>Sometimes we’ll want to sort a collection by something other than its natural order. For example, suppose we wanted to sort strings by their length instead of alphabetically. Here’s an example of custom sorts sorts in Go.</p> </td> <td class="code empty leading"> </td> </tr> <tr> <td class="docs"> </td> <td class="code leading"> <a href="http://play.golang.org/p/M06NADP985"><img title="Run code" src="play.png" class="run" /></a> <div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span> </pre></div> </td> </tr> <tr> <td class="docs"> </td> <td class="code leading"> <div class="highlight"><pre><span class="kn">import</span> <span class="s">"sort"</span> <span class="kn">import</span> <span class="s">"fmt"</span> </pre></div> </td> </tr> <tr> <td class="docs"> <p>In order to sort by a custom function in Go, we need a corresponding type. Here we’ve created a <code>ByLength</code> type that is just an alias for the builtin <code>[]string</code> type.</p> </td> <td class="code leading"> <div class="highlight"><pre><span class="kd">type</span> <span class="nx">ByLength</span> <span class="p">[]</span><span class="kt">string</span> </pre></div> </td> </tr> <tr> <td class="docs"> <p>We implement <code>sort.Interface</code> - <code>Len</code>, <code>Less</code>, and <code>Swap</code> - on our type so we can use the <code>sort</code> package’s generic <code>Sort</code> function. <code>Len</code> and <code>Swap</code> will usually be similar across types and <code>Less</code> will hold the actual custom sorting logic. In our case we want to sort in order of increasing string length, so we use <code>len(s[i])</code> and <code>len(s[j])</code> here.</p> </td> <td class="code leading"> <div class="highlight"><pre><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="nx">ByLength</span><span class="p">)</span> <span class="nx">Len</span><span class="p">()</span> <span class="kt">int</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="nx">s</span><span class="p">)</span> <span class="p">}</span> <span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="nx">ByLength</span><span class="p">)</span> <span class="nx">Swap</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">j</span> <span class="kt">int</span><span class="p">)</span> <span class="p">{</span> <span class="nx">s</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">s</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span> <span class="p">=</span> <span class="nx">s</span><span class="p">[</span><span class="nx">j</span><span class="p">],</span> <span class="nx">s</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="p">}</span> <span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="nx">ByLength</span><span class="p">)</span> <span class="nx">Less</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">j</span> <span class="kt">int</span><span class="p">)</span> <span class="kt">bool</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="nx">s</span><span class="p">[</span><span class="nx">i</span><span class="p">])</span> <span class="p"><</span> <span class="nb">len</span><span class="p">(</span><span class="nx">s</span><span class="p">[</span><span class="nx">j</span><span class="p">])</span> <span class="p">}</span> </pre></div> </td> </tr> <tr> <td class="docs"> <p>With all of this in place, we can now implement our custom sort by casting the original <code>fruits</code> slice to <code>ByLength</code>, and then use <code>sort.Sort</code> on that typed slice.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span> <span class="nx">fruits</span> <span class="o">:=</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"peach"</span><span class="p">,</span> <span class="s">"banana"</span><span class="p">,</span> <span class="s">"kiwi"</span><span class="p">}</span> <span class="nx">sort</span><span class="p">.</span><span class="nx">Sort</span><span class="p">(</span><span class="nx">ByLength</span><span class="p">(</span><span class="nx">fruits</span><span class="p">))</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">fruits</span><span class="p">)</span> <span class="p">}</span> </pre></div> </td> </tr> </table> <table> <tr> <td class="docs"> <p>Running our program shows a list sorted by string length, as desired.</p> </td> <td class="code leading"> <div class="highlight"><pre><span class="gp">$</span> go run sorting-by-functions.go <span class="go">[kiwi peach banana]</span> </pre></div> </td> </tr> <tr> <td class="docs"> <p>By following this same pattern of creating a custom type, implementing the three <code>Interface</code> methods on that type, and then calling sort.Sort on a collection of that custom type, we can sort Go slices by arbitrary functions.</p> </td> <td class="code empty"> </td> </tr> </table> <p class="next"> Next example: <a href="panic">Panic</a>. </p> <p class="footer"> by <a href="https://twitter.com/mmcgrana">@mmcgrana</a> | <a href="mailto:mmcgrana@gmail.com">feedback</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/sorting-by-functions">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a> </p> </div> </body> </html>