Skip to content

Instantly share code, notes, and snippets.

@kyohsuke
Created July 5, 2026 03:41
Show Gist options
  • Select an option

  • Save kyohsuke/cd8db98bab9f12b267bd9afa5f21a93c to your computer and use it in GitHub Desktop.

Select an option

Save kyohsuke/cd8db98bab9f12b267bd9afa5f21a93c to your computer and use it in GitHub Desktop.
comm.go
package main
import (
"cmp"
"fmt"
)
type CommResult[T cmp.Ordered] struct {
OnlyA []T // column 1
OnlyB []T // column 2
Both []T // column 3
}
// cmp.Ordered を使うことで < や > の大小比較が可能になる
func CommSlices[T cmp.Ordered](a, b []T) CommResult[T] { // 返り値に [T] を明記
i, j := 0, 0
res := CommResult[T]{} // 初期化時にも [T] を明記
for i < len(a) || j < len(b) {
switch {
case i >= len(a):
res.OnlyB = append(res.OnlyB, b[j])
j++
case j >= len(b):
res.OnlyA = append(res.OnlyA, a[i])
i++
case a[i] < b[j]:
res.OnlyA = append(res.OnlyA, a[i])
i++
case a[i] > b[j]:
res.OnlyB = append(res.OnlyB, b[j])
j++
default: // a[i] == b[j]
// %s ではなく %v を使うことで、string 以外の型(int等)にも対応可能
fmt.Printf("a[%d]: %v / b[%d]: %v\n", i, a[i], j, b[j])
res.Both = append(res.Both, a[i])
i++
j++
}
}
return res
}
func main() {
a := []string{"apple", "banana", "carrot", "kiwi", "water melon"}
b := []string{"banana", "grape", "kiwi", "melon"}
fmt.Println("a:", a)
fmt.Println("b:", b)
r := CommSlices(a, b) // 引数から型推論されるため、ここは [string] を省略可能
fmt.Println("only a:", r.OnlyA) // [apple carrot water melon]
fmt.Println("only b:", r.OnlyB) // [grape melon]
fmt.Println("both :", r.Both) // [banana kiwi]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment