0Pricing
Go Academy · レッスン

カスタムソート順

比較関数を定義します

「カスタムソート順」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。

デフォルト順序以外のソート

デフォルトのソートは昇順です。しかし実際のデータでは、長さや複数のフィールド、計算結果など、独自のルールが必要になります。

比較関数を使って、必要なルールを自由に表現できます。

less関数

sort.Slice の比較関数のシグネチャは func(i, j int) bool です。要素 i を要素 j より前に置く場合に true を返します。

package main

import (
	"fmt"
	"sort"
)

func main() {
	nums := []int{4, 1, 3}
	less := func(i, j int) bool { return nums[i] < nums[j] }
	sort.Slice(nums, less)
	fmt.Println(nums)
}

文字列の長さでソートする

アルファベット順の代わりに、各文字列の len() を比較して長さ順に並べます。

package main

import (
	"fmt"
	"sort"
)

func main() {
	words := []string{"pear", "fig", "banana"}
	sort.Slice(words, func(i, j int) bool {
		return len(words[i]) < len(words[j])
	})
	fmt.Println(words)
}

フィールドで構造体をソートする

比較に使う構造体のフィールドを自由に選べます。ここでは商品の価格でソートします。

package main

import (
	"fmt"
	"sort"
)

type Product struct {
	Name  string
	Price int
}

func main() {
	items := []Product{{"Pen", 3}, {"Book", 12}, {"Cup", 7}}
	sort.Slice(items, func(i, j int) bool {
		return items[i].Price < items[j].Price
	})
	fmt.Println(items)
}

複数のフィールドでソートする

同順位を解消するには、最初のフィールドが等しい場合に2つ目のフィールドを比較します。年齢、次に名前の順でソートします。

package main

import (
	"fmt"
	"sort"
)

type Person struct {
	Name string
	Age  int
}

func main() {
	p := []Person{{"Zoe", 30}, {"Ann", 30}, {"Bob", 25}}
	sort.Slice(p, func(i, j int) bool {
		if p[i].Age != p[j].Age {
			return p[i].Age < p[j].Age
		}
		return p[i].Name < p[j].Name
	})
	fmt.Println(p)
}

sort.Reverse で逆順にする

sort.Reverse は sort.Interface をラップして順序を逆にします。sort.IntSlice のようなヘルパーと組み合わせて使います。

package main

import (
	"fmt"
	"sort"
)

func main() {
	nums := []int{1, 4, 2, 3}
	sort.Sort(sort.Reverse(sort.IntSlice(nums)))
	fmt.Println(nums)
}

sort.Interface

完全に制御するには、sort.Interface を実装します。必要なのは、Len()、Less(i, j int) bool、Swap(i, j int) の3つのメソッドです。

package main

import (
	"fmt"
	"sort"
)

type ByLen []string

func (s ByLen) Len() int           { return len(s) }
func (s ByLen) Less(i, j int) bool { return len(s[i]) < len(s[j]) }
func (s ByLen) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func main() {
	w := []string{"ccc", "a", "bb"}
	sort.Sort(ByLen(w))
	fmt.Println(w)
}

計算値でソートする

比較には任意の式を使えます。数値を0からの絶対距離でソートします。

package main

import (
	"fmt"
	"sort"
)

func abs(n int) int {
	if n < 0 {
		return -n
	}
	return n
}

func main() {
	nums := []int{-5, 2, -1, 3}
	sort.Slice(nums, func(i, j int) bool {
		return abs(nums[i]) < abs(nums[j])
	})
	fmt.Println(nums)
}

大文字と小文字を区別しないソート

比較処理の中で strings.ToLower を使うと、文字列の順序付けで大文字と小文字を区別しないようにできます。

package main

import (
	"fmt"
	"sort"
	"strings"
)

func main() {
	w := []string{"banana", "Apple", "cherry"}
	sort.Slice(w, func(i, j int) bool {
		return strings.ToLower(w[i]) < strings.ToLower(w[j])
	})
	fmt.Println(w)
}

Slice と Interface の使い分け

順序をカスタマイズする方法は2つあります。

  • sort.Slice - 手軽なインラインの less関数
  • sort.Interface - 3つのメソッドを持つ再利用可能な名前付き型

一度しか使わないソートには sort.Slice を優先してください。

比較処理を純粋に保つ

比較関数は要素を読み取り、boolを返すだけにしてください。スライスを変更したり副作用を起こしたりしてはいけません。そうしないと、ソートが予測できない動作をする可能性があります。

確認問題

人物を年齢でソートし、年齢が同じ場合は名前でソートしたいとします。どの手法を使いますか。

まとめ

任意のソート順を定義できます。

  • less関数でルールを表現します
  • 複数フィールドのソートでは、同順位の場合に2つ目のフィールドを比較します
  • sort.Reverse で順序を逆にし、sort.Interface で再利用可能な型を定義できます

よくある質問

「カスタムソート順」レッスンは無料ですか?

はい。「カスタムソート順」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。

「カスタムソート順」で何を学びますか?

比較関数を定義します ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Go Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「カスタムソート順」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このGo Academyレッスンでコードを書いて実行できますか?

はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. スライスのソート
  2. カスタムソート順
  3. ソート済みデータの検索
  4. 安定ソート
← Go Academyに戻る