gobyexample/public/sorting-by-functions
2019-10-14 23:20:44 +03:00

186 lines
9.2 KiB
Plaintext
Generated
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Go в примерах: Сортировка через функции (Sorting by Functions)</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'sorting';
}
if (e.key == "ArrowRight") {
window.location.href = 'panic';
}
}
</script>
<body>
<div class="example" id="sorting-by-functions">
<h2><a href="./">Go в примерах</a>: Сортировка через функции (Sorting by Functions)</h2>
<table>
<tr>
<td class="docs">
<p>Иногда мы хотим отсортировать коллекцию по какому-то
другому признаку, кроме ее естественного порядка.
Например, предположим, что мы хотели бы отсортировать
строки по длине, а не по алфавиту. Вот пример
пользовательских сортировок в 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/VQrgvKKcvRg" target="_blank"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<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="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;sort&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Для сортировки по пользовательской функции в Go нам
нужен соответствующий тип. Здесь мы создали тип
<code>byLength</code>, который является просто псевдонимом для
<code>[]string</code>.</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>Мы реализуем <code>sort.Interface</code> - Len<code>,</code>Less<code>и</code>Swap<code>
- для нашего типа, чтобы мы могли использовать общую
функцию</code>Sort<code>пакета</code>sort<code>.</code>Len<code>и</code>Swap<code>обычно
одинаковы для разных типов, а</code>Less<code>будет содержать
реальную пользовательскую логику сортировки. В нашем
случае мы хотим отсортировать в порядке увеличения
длины строки, поэтому мы используем</code>len(s[i])<code>и
</code>len(s[j])` здесь.</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">&lt;</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>Реализовав интерфейс, мы можем теперь реализовать
нашу собственную сортировку, преобразовав исходный
срез <code>fruits</code> в <code>byLength</code>, а затем использовать
<code>sort.Sort</code> для этого типизированного среза.</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">&quot;peach&quot;</span><span class="p">,</span> <span class="s">&quot;banana&quot;</span><span class="p">,</span> <span class="s">&quot;kiwi&quot;</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>При запуске нашей программы отображается список,
отсортированный по длине строки, как мы и хотели.</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>Следуя той же схеме создания пользовательского типа,
реализации трех методов <code>интерфейса</code> для этого типа
и последующего вызова <code>sort.Sort</code> для коллекции
этого типа, мы можем сортировать срезы Go
по произвольным функциям.</p>
</td>
<td class="code empty">
</td>
</tr>
</table>
<p class="next">
Следующий пример: <a href="panic">Panic</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</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>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"sort\"\u000A)\u000A');codeLines.push('type byLength []string\u000A');codeLines.push('func (s byLength) Len() int {\u000A return len(s)\u000A}\u000Afunc (s byLength) Swap(i, j int) {\u000A s[i], s[j] = s[j], s[i]\u000A}\u000Afunc (s byLength) Less(i, j int) bool {\u000A return len(s[i]) \x3C len(s[j])\u000A}\u000A');codeLines.push('func main() {\u000A fruits := []string{\"peach\", \"banana\", \"kiwi\"}\u000A sort.Sort(byLength(fruits))\u000A fmt.Println(fruits)\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>