はじめに
前回の記事では Go 1.23 で追加された iter パッケージについて紹介しましたが、Go 1.23では slices パッケージと maps パッケージにも関連する関数が追加されました。
今回はそれらの関数についてまとめて紹介します。
slicesパッケージに追加された関数
slices パッケージには以下の関数が追加されました。
関数名 | 関数の説明 |
All | slice内のindexとvalueのペアをiteratorとして返す |
Backward | Allと同様の返却値を逆順で返す |
Values | sliceの要素を順番に返すiteratorを返す |
AppendSeq | appendしたsliceを返すiteratorを返す |
Collect | iteratorをsliceに変換する |
Sorted | iteratorをsliceに変換した上でsortする |
SortedFunc | ソート関数を渡せるSorted |
SortedStableFunc | ソート関数を渡した上で安定ソートしたSorted |
Chunk | 指定した要素数毎に区切ったiteratorを返す |
それぞれの関数について見ていきます。
All
Allはシンプルにsliceをiteratorに変換して返します。
Allのシグネチャは以下のとおりです。
func All[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package main import ( "fmt" "iter" "slices" ) func main() { vs := []int{1, 2, 3, 4, 5} iterator := slices.All(vs) // そのまま使う場合 for k, v := range iterator { fmt.Printf("%d: %d\n", k, v) } // pull型に変換して使う場合 next, _ := iter.Pull2(iterator) for { k, v, ok := next() if !ok { break } fmt.Printf("%d: %d\n", k, v) } } |
実行結果
1 2 3 4 5 6 7 8 9 10 | 0: 1 1: 2 2: 3 3: 4 4: 5 0: 1 1: 2 2: 3 3: 4 4: 5 |
Backward
BackwardはAllを逆順で返したものです。
Backwardのシグネチャは以下のとおりです。
func Backward[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "fmt" "slices" ) func main() { vs := []int{1, 2, 3, 4, 5} for k, v := range slices.Backward(vs) { fmt.Printf("%d: %d\n", k, v) } } |
実行結果
1 2 3 4 5 | 4: 5 3: 4 2: 3 1: 2 0: 1 |
Values
Valuesはsliceを引数が1つのiteratorに変換します。
Valuesのシグネチャは以下のとおりです。
func Values[Slice ~[]E, E any](s Slice) iter.Seq[E]
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "fmt" "slices" ) func main() { vs := []int{1, 2, 3, 4, 5} for v := range slices.Values(vs) { fmt.Printf("%d\n", v) } } |
実行結果
1 2 3 4 5 | 1 2 3 4 5 |
ちなみに、
iter.Seq[E]
(返り値が1つ)では、sliceを渡した時のようにindexを受け取ろうとするとエラーになります。
1 2 3 | for i, v := range slices.Values(vs) { fmt.Printf("%d: %d\n", i, v) } |
エラーメッセージ
1 | ./main.go:10:9: range over slices.Values(vs) (value of type iter.Seq[int]) permits only one iteration variable |
AppendSeq
AppendSeqはsliceにiteratorの返却値をappendしたsliceを返します。
AppendSeqのシグネチャは以下のとおりです。
func AppendSeq[Slice ~[]E, E any](s Slice, seq iter.Seq[E]) Slice
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package main import ( "fmt" "slices" ) func main() { v1s := []int{1, 2, 3, 4, 5} iterator := slices.Values([]int{6, 7, 8}) v2s := slices.AppendSeq(v1s, iterator) for i, v := range v2s { fmt.Printf("%d: %d\n", i, v) } } |
実行結果
1 2 3 4 5 6 7 | 0: 1 1: 2 2: 3 3: 4 4: 5 5: 6 6: 7 |
Collect
Collectはiteratorをsliceに変換します。
Collectのシグネチャは以下のとおりです。
func Collect[E any](seq iter.Seq[E]) []E
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import ( "fmt" "slices" ) func main() { iterator := slices.Values([]int{1, 2, 3, 4, 5}) vs := slices.Collect(iterator) for i, v := range vs { fmt.Printf("%d: %d\n", i, v) } } |
実行結果
1 2 3 4 5 | 0: 1 1: 2 2: 3 3: 4 4: 5 |
SortedFunc
SortedFuncはiteratorをsliceに変換した上で、引数で渡した関数でsortした結果を返します。
なお、
Sorted
および
SortedStableFunc
については、
SortedFunc
の使い方と近しいため省略します。
SortedFuncのシグネチャは以下のとおりです。
func SortedFunc[E any](seq iter.Seq[E], cmp func(E, E) int) []E
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package main import ( "fmt" "slices" ) func main() { type Book struct { Title string Price int } iterator := slices.Values([]Book{ {"A", 100}, {"B", 200}, {"C", 300}, }) f := func(v1, v2 Book) int { return v1.Price - v2.Price } for i, v := range slices.SortedFunc(iterator, f) { fmt.Printf("%d: %+v\n", i, v) } } |
実行結果
1 2 3 | 0: {Title:A Price:100} 1: {Title:B Price:200} 2: {Title:C Price:300} |
Chunk
Collectはsliceを指定した要素数毎に区切ったiteratorに変換して返します。
Collectのシグネチャは以下のとおりです。
func Chunk[Slice ~[]E, E any](s Slice, n int) iter.Seq[Slice]
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "fmt" "slices" ) func main() { vs := []int{1, 2, 3, 4, 5} for s := range slices.Chunk(vs, 2) { fmt.Printf("%+v\n", s) } } |
実行結果
1 2 3 | [1 2] [3 4] [5] |
mapsパッケージに追加された関数
maps パッケージには以下の関数が追加されました。
関数名 | 関数の説明 |
All | mapをkeyとvalueのペアを返すiteratorに変換する |
Keys | mapのkeyを返すiteratorに変換する |
Values | mapのvalueを返すiteratorに変換する |
Insert | mapにiteratorのkeyとvalueを追加する |
Collect | iteratorをmapに変換する |
それぞれの関数について見ていきます。
All
Allはシンプルにmapをiteratorに変換して返します。
Allのシグネチャは以下のとおりです。
func All[Map ~map[K]V, K comparable, V any](m Map) iter.Seq2[K, V]
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "fmt" "maps" ) func main() { m := map[string]int{"a": 1, "b": 2, "c": 3} for k, v := range maps.All(m) { fmt.Printf("%s: %d\n", k, v) } } |
実行結果
1 2 3 | a: 1 b: 2 c: 3 |
Keys
Keysはmapのkeyを返すiteratorを返します。
Keysのシグネチャは以下のとおりです。
func Keys[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[K]
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "fmt" "maps" ) func main() { m := map[string]int{"a": 1, "b": 2, "c": 3} for k := range maps.Keys(m) { fmt.Printf("%s\n", k) } } |
実行結果
1 2 3 4 5 6 7 8 9 10 | 0: 1 1: 2 2: 3 3: 4 4: 5 0: 1 1: 2 2: 3 3: 4 4: 5 |
Values
Valuesはmapのvalueを返すiteratorを返します。
Valuesのシグネチャは以下のとおりです。
func Values[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[V]
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "fmt" "maps" ) func main() { m := map[string]int{"a": 1, "b": 2, "c": 3} for v := range maps.Values(m) { fmt.Printf("%d\n", v) } } |
実行結果
1 2 3 | 2 3 1 |
Insert
Insertはmapにiteratorのkeyとvalueを追加したmapを返します。この際、keyが重複する場合はiteratorのvalueで上書きされます。
Insertのシグネチャは以下のとおりです。
func Insert[Map ~map[K]V, K comparable, V any](m Map, seq iter.Seq2[K, V])
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package main import ( "fmt" "maps" ) func main() { m := map[string]int{"a": 1, "b": 2, "c": 3} iterator := maps.All(map[string]int{"c": 13, "d": 4, "e": 5}) maps.Insert(m, iterator) for k, v := range m { fmt.Printf("%s, %d\n", k, v) } } |
実行結果
1 2 3 4 5 | a, 1 b, 2 c, 13 e, 5 d, 4 |
Collect
Collectはiteratorをmapに変換して返します。
Collectのシグネチャは以下のとおりです。
func Collect[K comparable, V any](seq iter.Seq2[K, V]) map[K]V
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "fmt" "maps" ) func main() { iterator := maps.All(map[string]int{"a": 1, "b": 2, "c": 3}) for k, v := range maps.Collect(iterator) { fmt.Printf("%s, %d\n", k, v) } } |
実行結果
1 2 3 | a, 1 b, 2 c, 3 |
さいごに
前回紹介した iter パッケージに関連する新しい関数について紹介しました。