HOWTO · Go

構造体の GoLang ソート スライス

このチュートリアルでは、GoLang で構造体のスライスを並べ替える方法を示します。

このページの内容

このチュートリアルでは、GoLang で構造体のスライスを並べ替える方法を示します。

構造体の GoLang ソート スライス

GoLang には、構造体のスライスをソートするための 2つのメソッドが用意されています。 1つは sort.Slice で、もう 1つは sort.SliceStable です。 また、構造体のスライスをソートするには、これら 2つのメソッドとともに less 関数を使用する必要があります。

これらのメソッドの構文は次のとおりです。

//sort.Slice
func Slice(x StructSlice, less func(i, j int) bool)

//sort.SliceStable
func Slice(x StructSlice, less func(i, j int) bool)

x が構造体のスライスである場合、スライスは less 関数に基づいてソートされます。 GoLang で構造体のスライスをソートする方法を理解するために、いくつかの例を実装してみましょう。

構造体のスライスをフィールドで並べ替える

フィールドによる構造体のスライスのソートは、構造体のスライスのソートの基本的な例です。 フィールドに基づいて構造体スライスのメンバーの値を同じ構造体スライスの他のメンバーと比較する例を見てみましょう。

package main

import (
    "fmt"
    "sort"
)

type Employee struct {
    Name   string
    Salary int
}

func main() {
    // Sort in Ascending order
    employees := []Employee{
        {Name: "John", Salary: 1500},
        {Name: "Joe", Salary: 3000},
        {Name: "Jack", Salary: 3400},
    }

    sort.Slice(employees, func(i, j int) bool {
        return employees[i].Salary < employees[j].Salary
    })

    fmt.Println(employees)

    // Sort in Descending order
    employees1 := []Employee{
        {Name: "John", Salary: 1500},
        {Name: "Joe", Salary: 3000},
        {Name: "Jack", Salary: 3400},
    }

    sort.Slice(employees1, func(i, j int) bool {
        return employees1[i].Salary > employees1[j].Salary
    })

    fmt.Println(employees1)
}

上記のコードには、NameSalary の 2つのフィールドを持つ構造体 Employee が含まれており、構造体のスライスを作成し、Slice メソッドを使用してフィールド Salary に基づいて昇順に並べ替え、次に 別のスライスを降順に並べ替えます。

出力を参照してください。

[{John 1500} {Joe 3000} {Jack 3400}]
[{Jack 3400} {Joe 3000} {John 1500}]

現在、これらのタイプのスライスでは sort.SliceStable を使用できません。これには、フィールド名と値のキーと値のペア (マップ) が含まれます。 sort.SliceStable を使用すると、値のみを含む構造体の単純なスライスをソートできます。

package main

import (
    "fmt"
    "sort"
)

type Employee struct {
    Name   string
    Salary int
}

func main() {
    // Sort in Ascending order
    employees := []Employee{
        {"John", 1500},
        {"Joe", 3000},
        {"Jack", 3400},
    }

    sort.SliceStable(employees, func(i, j int) bool {
        return employees[i].Salary < employees[j].Salary
    })

    fmt.Println(employees)

    // Sort in Descending order
    employees1 := []Employee{
        {"John", 1500},
        {"Joe", 3000},
        {"Jack", 3400},
    }

    sort.SliceStable(employees1, func(i, j int) bool {
        return employees1[i].Salary > employees1[j].Salary
    })

    fmt.Println(employees1)
}

上記のコードは、構造体のスライスに名前と値のキーと値のペアがないフィールドに基づいて、構造体のスライスを同様に並べ替えます。

出力を参照してください。

[{John 1500} {Joe 3000} {Jack 3400}]
[{Jack 3400} {Joe 3000} {John 1500}]

複数のフィールドによる構造体のスライスの並べ替え

複数のフィールドで構造体のスライスをソートすることも可能です。 less 関数を拡張する必要があります。 例を試してみましょう。

package main

import (
    "fmt"
    "sort"
)

type Employee struct {
    Name     string
    Position string
}

func main() {
    // Sort in Descending order
    employees := []Employee{
        {"Michael", "Developer"},
        {"Jack", "Manager"},
        {"Joe", "CEO"},
        {"Leonard", "Intern"},
        {"Sheldon", "Developer"},
    }

    sort.SliceStable(employees, func(i, j int) bool {
        if employees[i].Position != employees[j].Position {
            return employees[i].Position < employees[j].Position
        }

        return employees[i].Name < employees[j].Name
    })

    fmt.Println(employees)

    // Sort in Ascending order
    employees1 := []Employee{
        {"Michael", "Developer"},
        {"Jack", "Manager"},
        {"Joe", "CEO"},
        {"Leonard", "Intern"},
        {"Sheldon", "Developer"},
    }

    sort.SliceStable(employees1, func(i, j int) bool {
        if employees1[i].Position != employees1[j].Position {
            return employees1[i].Position > employees1[j].Position
        }

        return employees1[i].Name > employees1[j].Name
    })

    fmt.Println(employees1)
}

上記のコードは、NamePosition の両方に基づいて並べ替えます。2 人の従業員の役職が同じ場合は、Name フィールドに従って並べ替えられます。 構造体のスライスは、降順および昇順でソートされます。

出力を参照してください。

[{Joe CEO} {Michael Developer} {Sheldon Developer} {Leonard Intern} {Jack Manager}]
[{Jack Manager} {Leonard Intern} {Sheldon Developer} {Michael Developer} {Joe CEO}]