-
Notifications
You must be signed in to change notification settings - Fork 5
/
map.go
61 lines (49 loc) · 1.72 KB
/
map.go
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
Copyright 2023, 2024 Dima Krasner
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package data
type valueAndIndex[TV any] struct {
value TV
index int
}
// OrderedMap is a map that maintains insertion order. Listing of keys (using [OrderedMap.Keys]) iterates over keys and allocates memory.
type OrderedMap[TK comparable, TV any] map[TK]valueAndIndex[TV]
// Contains determines if the map contains a key.
func (m OrderedMap[TK, TV]) Contains(key TK) bool {
_, contains := m[key]
return contains
}
// Store adds a key/value pair to the map if the map doesn't contain it already.
func (m OrderedMap[TK, TV]) Store(key TK, value TV) {
if _, dup := m[key]; !dup {
m[key] = valueAndIndex[TV]{value, len(m)}
}
}
// Keys returns a list of keys in the map.
// To do so, it iterates over keys and allocates memory.
func (m OrderedMap[TK, TV]) Keys() []TK {
l := make([]TK, len(m))
for k, v := range m {
l[v.index] = k
}
return l
}
// Range iterates over the map and calls a callback for each key/value pair.
// Iteration stops if the callback returns false.
// Range calls [OrderedMap.Keys], therefore it allocates memory.
func (m OrderedMap[TK, TV]) Range(f func(key TK, value TV) bool) {
for _, k := range m.Keys() {
if !f(k, m[k].value) {
break
}
}
}