はじめに
Go で map 内のデータを検索するサンプル
サンプル
package main import "errors" func MapSearch(nums, length []int) ([]int, error) { targetMap := make(map[int]int, len(nums)) for i, nums := range nums { targetMap[nums] = i } target := make([]int, len(length)) for si, s := range length { if ti, ok := targetMap[s]; ok { target[si] = ti } else { return nil, errors.New("not found") } } return target, nil } func main() { nums := []int{1, 2, 3, 4, 5} length := []int{1, 3, 5} target, err := MapSearch(nums, length) if err != nil { println(err.Error()) return } for _, t := range target { println(t) } }
テスト
package main import ( "reflect" "testing" ) func Test_MapSearch(t *testing.T) { tests := []struct { name string nums []int target []int expected []int }{ {"MapSearch", []int{1, 2, 3, 4, 5}, []int{1, 3, 5}, []int{0, 2, 4}}, } fv := reflect.ValueOf(MapSearch) name := runtime.FuncForPC(fv.Pointer()).Name() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := MapSearch(tt.nums, tt.target) if err != nil { t.Errorf("Error: %v", err) } if !reflect.DeepEqual(got, tt.expected) { t.Errorf(name+"() = %v, want %v", got, tt.expected) } }) } }
ベンチマークコード
package main import ( "testing" ) func makeSeqNums(count int) []int { nums := make([]int, count) for i := 0; i < count; i++ { nums[i] = i + 1 } return nums } func BenchmarkMapSearch(b *testing.B) { nums := makeSeqNums(10000) target := makeSeqNums(50000) b.ResetTimer() for i := 0; i < b.N; i++ { MapSearch(nums, target) } }
% go test -bench . -benchmem goos: linux goarch: amd64 pkg: go-map-search cpu: Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz BenchmarkMapSearch-2 1310 875660 ns/op 723626 B/op 13 allocs/op PASS ok go-map-search 1.252s