mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
lang: add a helper for iterating a map in order (#18809)
In some cases it is helpful to iterate a map in the sorted order of the maps keyset - particularly in implementations of some function for which the tests cannot be deterministic without order.
This commit is contained in:
27
lib/lang/maps.go
Normal file
27
lib/lang/maps.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package lang
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// WalkMap will call f for every k/v in m, iterating the keyset of m in the
|
||||
// cmp.Ordered order. If f returns false the iteration is halted early.
|
||||
func WalkMap[K cmp.Ordered, V any](m map[K]V, f func(K, V) bool) {
|
||||
keys := make([]K, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
// sort keys ascending
|
||||
slices.Sort(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
if !f(k, m[k]) {
|
||||
return // stop iteration
|
||||
}
|
||||
}
|
||||
}
|
||||
55
lib/lang/maps_test.go
Normal file
55
lib/lang/maps_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package lang
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/shoenig/test/must"
|
||||
)
|
||||
|
||||
func TestWalkMap(t *testing.T) {
|
||||
m := map[int]string{
|
||||
1: "one",
|
||||
3: "three",
|
||||
4: "four",
|
||||
2: "two",
|
||||
5: "five",
|
||||
}
|
||||
|
||||
result := make([]string, 0, 5)
|
||||
|
||||
f := func(_ int, v string) bool {
|
||||
result = append(result, v)
|
||||
return true
|
||||
}
|
||||
|
||||
WalkMap(m, f)
|
||||
|
||||
must.Eq(t, []string{"one", "two", "three", "four", "five"}, result)
|
||||
}
|
||||
|
||||
func TestWalkMap_halt(t *testing.T) {
|
||||
m := map[int]string{
|
||||
5: "five",
|
||||
1: "one",
|
||||
3: "three",
|
||||
4: "four",
|
||||
}
|
||||
|
||||
result := make([]string, 0, 3)
|
||||
|
||||
f := func(k int, v string) bool {
|
||||
if k%2 == 0 {
|
||||
// halt if we find an even key
|
||||
return false
|
||||
}
|
||||
result = append(result, v)
|
||||
return true
|
||||
}
|
||||
|
||||
WalkMap(m, f)
|
||||
|
||||
must.Eq(t, []string{"one", "three"}, result)
|
||||
}
|
||||
Reference in New Issue
Block a user