• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

enetx / g / 17137803990

20 Aug 2025 07:45PM UTC coverage: 90.116% (-1.3%) from 91.422%
17137803990

push

github

enetx
fix data race

56 of 58 new or added lines in 2 files covered. (96.55%)

182 existing lines in 5 files now uncovered.

5771 of 6404 relevant lines covered (90.12%)

671.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.3
/map_ordered.go
1
package g
2

3
import (
4
        "fmt"
5
        "slices"
6

7
        "github.com/enetx/g/cmp"
8
        "github.com/enetx/g/f"
9
        "github.com/enetx/g/rand"
10
)
11

12
// NewMapOrd creates a new ordered Map with the specified size (if provided).
13
// An ordered Map is an Map that maintains the order of its key-value pairs based on the
14
// insertion order. If no size is provided, the default size will be used.
15
//
16
// Parameters:
17
//
18
// - size ...int: (Optional) The initial size of the ordered Map. If not provided, a default size
19
// will be used.
20
//
21
// Returns:
22
//
23
// - MapOrd[K, V]: Ordered Map with the specified initial size (or default
24
// size if not provided).
25
//
26
// Example usage:
27
//
28
//        mapOrd := g.NewMapOrd[string, int](10)
29
//
30
// Creates a new ordered Map with an initial size of 10.
31
func NewMapOrd[K, V any](size ...Int) MapOrd[K, V] {
114✔
32
        return make(MapOrd[K, V], 0, Slice[Int](size).Get(0).UnwrapOrDefault())
114✔
33
}
114✔
34

35
// Transform applies a transformation function to the MapOrd and returns the result.
36
func (mo MapOrd[K, V]) Transform(fn func(MapOrd[K, V]) MapOrd[K, V]) MapOrd[K, V] { return fn(mo) }
2✔
37

38
// AsAny converts all key-value pairs in the MapOrd to type `any`.
39
//
40
// It returns a new MapOrd[any, any], where both keys and values are of type `any`.
41
// This is useful when working with dynamic formatting tools like Println or Format,
42
// which can access map elements dynamically when keys and values are of type `any`.
43
//
44
// Example:
45
//
46
//        mo := NewMapOrd[string, int]()
47
//        mo.Set("a", 1)
48
//        mo.Set("b", 2)
49
//
50
//        Println("{1.a} -> {1.b}", mo.AsAny())
51
//        // Output: "a -> 1"
52
func (mo MapOrd[K, V]) AsAny() MapOrd[any, any] {
1✔
53
        if mo.Empty() {
1✔
54
                return NewMapOrd[any, any]()
×
55
        }
×
56

57
        anymo := make(MapOrd[any, any], len(mo))
1✔
58
        for i, v := range mo {
2✔
59
                anymo[i] = Pair[any, any]{v.Key, v.Value}
1✔
60
        }
1✔
61

62
        return anymo
1✔
63
}
64

65
// Entry returns a MapOrdEntry object for the given key, providing fine-grained
66
// control over insertion, mutation, and deletion of its value in the ordered Map,
67
// while preserving the insertion order.
68
//
69
// Example:
70
//
71
//        mo := g.NewMapOrd[string, int]()
72
//        // Insert 1 if "foo" is absent, then increment it
73
//        e := mo.Entry("foo")
74
//        e.OrSet(1).
75
//        e.Transform(func(v int) int { return v + 1 })
76
//
77
// The entire operation requires only a single key lookup and works without
78
// additional allocations.
79
func (mo *MapOrd[K, V]) Entry(key K) MapOrdEntry[K, V] { return MapOrdEntry[K, V]{mo, key} }
10✔
80

81
// Iter returns an iterator (SeqMapOrd[K, V]) for the ordered Map, allowing for sequential iteration
82
// over its key-value pairs. It is commonly used in combination with higher-order functions,
83
// such as 'ForEach', to perform operations on each key-value pair of the ordered Map.
84
//
85
// Returns:
86
//
87
// A SeqMapOrd[K, V], which can be used for sequential iteration over the key-value pairs of the ordered Map.
88
//
89
// Example usage:
90
//
91
//        m := g.NewMapOrd[int, int]()
92
//        m.Set(1, 1)
93
//        m.Set(2, 2)
94
//        m.Set(3, 3).
95
//
96
//        m.Iter().ForEach(func(k, v int) {
97
//            // Process key-value pair
98
//        })
99
//
100
// The 'Iter' method provides a convenient way to traverse the key-value pairs of an ordered Map
101
// in a functional style, enabling operations like mapping or filtering.
102
func (mo MapOrd[K, V]) Iter() SeqMapOrd[K, V] {
48✔
103
        return func(yield func(K, V) bool) {
96✔
104
                for _, v := range mo {
184✔
105
                        if !yield(v.Key, v.Value) {
146✔
106
                                return
10✔
107
                        }
10✔
108
                }
109
        }
110
}
111

112
// IterReverse returns an iterator (SeqMapOrd[K, V]) for the ordered Map that allows for sequential iteration
113
// over its key-value pairs in reverse order. This method is useful when you need to process the elements
114
// from the last to the first.
115
//
116
// Returns:
117
//
118
// A SeqMapOrd[K, V], which can be used for sequential iteration over the key-value pairs of the ordered Map in reverse order.
119
//
120
// Example usage:
121
//
122
//        m := g.NewMapOrd[int, int]()
123
//        m.Set(1, 1)
124
//        m.Set(2, 2)
125
//        m.Set(3, 3)
126
//
127
//        m.IterReverse().ForEach(func(k, v int) {
128
//            // Process key-value pair in reverse order
129
//            fmt.Println("Key:", k, "Value:", v)
130
//        })
131
//
132
// The 'IterReverse' method complements the 'Iter' method by providing a way to access the elements
133
// in a reverse sequence, offering additional flexibility in data processing scenarios.
134
func (mo MapOrd[K, V]) IterReverse() SeqMapOrd[K, V] {
3✔
135
        return func(yield func(K, V) bool) {
6✔
136
                for i := len(mo) - 1; i >= 0; i-- {
7✔
137
                        v := mo[i]
4✔
138
                        if !yield(v.Key, v.Value) {
4✔
139
                                return
×
140
                        }
×
141
                }
142
        }
143
}
144

145
// MapOrdFromStd converts a standard Go map to an ordered Map.
146
// The resulting ordered Map will maintain the order of its key-value pairs based on the order of
147
// insertion.
148
// This function is useful when you want to create an ordered Map from an existing Go map.
149
//
150
// Parameters:
151
//
152
// - m map[K]V: The input Go map to be converted to an ordered Map.
153
//
154
// Returns:
155
//
156
// - MapOrd[K, V]: New ordered Map containing the same key-value pairs as the
157
// input Go map.
158
//
159
// Example usage:
160
//
161
//        mapOrd := g.MapOrdFromStd[string, int](goMap)
162
//
163
// Converts the standard Go map 'map[K]V' to an ordered Map.
164
func MapOrdFromStd[K comparable, V any](m map[K]V) MapOrd[K, V] { return Map[K, V](m).ToMapOrd() }
2✔
165

166
// SortBy sorts the ordered Map by a custom comparison function.
167
//
168
// Parameters:
169
//
170
// - fn func(a, b Pair[K, V]) cmp.Ordering: The custom comparison function used for sorting the ordered Map.
171
//
172
// Example usage:
173
//
174
//        hmapo.SortBy(func(a, b g.Pair[g.String, g.Int]) cmp.Ordering { return a.Key.Cmp(b.Key) })
175
//        hmapo.SortBy(func(a, b g.Pair[g.String, g.Int]) cmp.Ordering { return a.Value.Cmp(b.Value) })
176
func (mo MapOrd[K, V]) SortBy(fn func(a, b Pair[K, V]) cmp.Ordering) {
3✔
177
        slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a, b)) })
11✔
178
}
179

180
// SortByKey sorts the ordered MapOrd[K, V] by the keys using a custom comparison function.
181
//
182
// Parameters:
183
//
184
// - fn func(a, b K) cmp.Ordering: The custom comparison function used for sorting the keys.
185
//
186
// Example usage:
187
//
188
//        hmapo.SortByKey(func(a, b g.String) cmp.Ordering { return a.Cmp(b) })
189
func (mo MapOrd[K, V]) SortByKey(fn func(a, b K) cmp.Ordering) {
5✔
190
        slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a.Key, b.Key)) })
35✔
191
}
192

193
// SortByValue sorts the ordered MapOrd[K, V] by the values using a custom comparison function.
194
//
195
// Parameters:
196
//
197
// - fn func(a, b V) cmp.Ordering: The custom comparison function used for sorting the values.
198
//
199
// Example usage:
200
//
201
//        hmapo.SortByValue(func(a, b g.Int) cmp.Ordering { return a.Cmp(b) })
202
func (mo MapOrd[K, V]) SortByValue(fn func(a, b V) cmp.Ordering) {
1✔
203
        slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a.Value, b.Value)) })
3✔
204
}
205

206
// Clone creates a new ordered Map with the same key-value pairs.
207
func (mo MapOrd[K, V]) Clone() MapOrd[K, V] {
3✔
208
        if mo.Empty() {
4✔
209
                return NewMapOrd[K, V]()
1✔
210
        }
1✔
211

212
        result := make(MapOrd[K, V], len(mo))
2✔
213
        copy(result, mo)
2✔
214

2✔
215
        return result
2✔
216
}
217

218
// Copy copies key-value pairs from the source ordered Map to the current ordered Map.
219
func (mo *MapOrd[K, V]) Copy(src MapOrd[K, V]) {
2✔
220
        if src.Empty() {
3✔
221
                return
1✔
222
        }
1✔
223

224
        for _, srcPair := range src {
3✔
225
                if i := mo.index(srcPair.Key); i != -1 {
2✔
226
                        (*mo)[i].Value = srcPair.Value
×
227
                } else {
2✔
228
                        *mo = append(*mo, srcPair)
2✔
229
                }
2✔
230
        }
231
}
232

233
// // ToMap converts the ordered Map to a standard Map.
234
// func (mo MapOrd[K, V]) ToMap() Map[K, V] {
235
//         m := NewMap[K, V](len(mo))
236
//         mo.Iter().ForEach(func(k K, v V) { m.Set(k, v) })
237
//
238
//         return m
239
// }
240

241
// Set sets the value for the specified key in the ordered Map,
242
// and returns the previous value if it existed.
243
func (mo *MapOrd[K, V]) Set(key K, value V) Option[V] {
265✔
244
        if i := mo.index(key); i != -1 {
265✔
UNCOV
245
                prev := (*mo)[i].Value
×
UNCOV
246
                (*mo)[i].Value = value
×
UNCOV
247

×
UNCOV
248
                return Some(prev)
×
UNCOV
249
        }
×
250

251
        mp := Pair[K, V]{Key: key, Value: value}
265✔
252
        *mo = append(*mo, mp)
265✔
253

265✔
254
        return None[V]()
265✔
255
}
256

257
// Get returns the value associated with the given key, wrapped in Option[V].
258
//
259
// It returns Some(value) if the key exists, or None if it does not.
260
func (mo MapOrd[K, V]) Get(key K) Option[V] {
25✔
261
        if i := mo.index(key); i != -1 {
46✔
262
                return Some(mo[i].Value)
21✔
263
        }
21✔
264

265
        return None[V]()
4✔
266
}
267

268
// Shuffle randomly reorders the elements of the ordered Map.
269
// It operates in place and affects the original order of the map's entries.
270
//
271
// The function uses the crypto/rand package to generate random indices.
272
func (mo MapOrd[K, V]) Shuffle() {
1✔
273
        for i := mo.Len() - 1; i > 0; i-- {
5✔
274
                j := rand.N(i + 1)
4✔
275
                mo[i], mo[j] = mo[j], mo[i]
4✔
276
        }
4✔
277
}
278

279
// Invert inverts the key-value pairs in the ordered Map, creating a new ordered Map with the
280
// values as keys and the original keys as values.
281
func (mo MapOrd[K, V]) Invert() MapOrd[V, K] {
2✔
282
        if mo.Empty() {
3✔
283
                return NewMapOrd[V, K]()
1✔
284
        }
1✔
285

286
        result := make(MapOrd[V, K], 0, len(mo))
1✔
287
        for _, pair := range mo {
4✔
288
                result = append(result, Pair[V, K]{pair.Value, pair.Key})
3✔
289
        }
3✔
290

291
        return result
1✔
292
}
293

294
func (mo MapOrd[K, V]) index(key K) int {
359✔
295
        var zero K
359✔
296
        if f.IsComparable(zero) {
702✔
297
                for i, mp := range mo {
831✔
298
                        if f.Eq[any](mp.Key)(key) {
563✔
299
                                return i
75✔
300
                        }
75✔
301
                }
302

303
                return -1
268✔
304
        }
305

306
        for i, mp := range mo {
24✔
307
                if f.Eqd(mp.Key)(key) {
15✔
308
                        return i
7✔
309
                }
7✔
310
        }
311

312
        return -1
9✔
313
}
314

315
// Keys returns an Slice containing all the keys in the ordered Map.
316
func (mo MapOrd[K, V]) Keys() Slice[K] {
4✔
317
        if mo.Empty() {
4✔
318
                return NewSlice[K]()
×
319
        }
×
320

321
        keys := make(Slice[K], len(mo))
4✔
322
        for i, pair := range mo {
15✔
323
                keys[i] = pair.Key
11✔
324
        }
11✔
325

326
        return keys
4✔
327
}
328

329
// Values returns an Slice containing all the values in the ordered Map.
330
func (mo MapOrd[K, V]) Values() Slice[V] {
2✔
331
        if mo.Empty() {
3✔
332
                return NewSlice[V]()
1✔
333
        }
1✔
334

335
        values := make(Slice[V], len(mo))
1✔
336
        for i, pair := range mo {
4✔
337
                values[i] = pair.Value
3✔
338
        }
3✔
339

340
        return values
1✔
341
}
342

343
// Delete removes the specified keys from the ordered Map.
344
func (mo *MapOrd[K, V]) Delete(keys ...K) {
5✔
345
        if len(keys) == 0 || mo.Empty() {
6✔
346
                return
1✔
347
        }
1✔
348

349
        writePos := 0
4✔
350
        for readPos := 0; readPos < len(*mo); readPos++ {
15✔
351
                shouldDelete := false
11✔
352

11✔
353
                for _, delKey := range keys {
26✔
354
                        var zero K
15✔
355
                        if f.IsComparable(zero) {
30✔
356
                                if f.Eq[any]((*mo)[readPos].Key)(delKey) {
20✔
357
                                        shouldDelete = true
5✔
358
                                        break
5✔
359
                                }
360
                        } else {
×
361
                                if f.Eqd((*mo)[readPos].Key)(delKey) {
×
362
                                        shouldDelete = true
×
363
                                        break
×
364
                                }
365
                        }
366
                }
367

368
                if !shouldDelete {
17✔
369
                        if writePos != readPos {
8✔
370
                                (*mo)[writePos] = (*mo)[readPos]
2✔
371
                        }
2✔
372
                        writePos++
6✔
373
                }
374
        }
375

376
        *mo = (*mo)[:writePos]
4✔
377
}
378

379
// Eq compares the current ordered Map to another ordered Map and returns true if they are equal.
380
func (mo MapOrd[K, V]) Eq(other MapOrd[K, V]) bool {
24✔
381
        n := len(mo)
24✔
382

24✔
383
        if n != len(other) {
26✔
384
                return false
2✔
385
        }
2✔
386

387
        if n == 0 {
25✔
388
                return true
3✔
389
        }
3✔
390

391
        var zero V
19✔
392
        comparable := f.IsComparable(zero)
19✔
393

19✔
394
        for i, mp := range mo {
71✔
395
                if other.index(mp.Key) != i {
53✔
396
                        return false
1✔
397
                }
1✔
398

399
                value := other[i].Value
51✔
400

51✔
401
                if comparable && !f.Eq[any](value)(mp.Value) || !comparable && !f.Eqd(value)(mp.Value) {
52✔
402
                        return false
1✔
403
                }
1✔
404
        }
405

406
        return true
17✔
407
}
408

409
// String returns a string representation of the ordered Map.
410
func (mo MapOrd[K, V]) String() string {
5✔
411
        if len(mo) == 0 {
6✔
412
                return "MapOrd{}"
1✔
413
        }
1✔
414

415
        var b Builder
4✔
416
        b.WriteString("MapOrd{")
4✔
417

4✔
418
        first := true
4✔
419
        for _, pair := range mo {
12✔
420
                if !first {
12✔
421
                        b.WriteString(", ")
4✔
422
                }
4✔
423

424
                first = false
8✔
425
                b.WriteString(Format("{}:{}", pair.Key, pair.Value))
8✔
426
        }
427

428
        b.WriteString("}")
4✔
429

4✔
430
        return b.String().Std()
4✔
431
}
432

433
// Clear removes all key-value pairs from the ordered Map.
434
func (mo *MapOrd[K, V]) Clear() { *mo = (*mo)[:0] }
2✔
435

436
// Contains checks if the ordered Map contains the specified key.
437
func (mo MapOrd[K, V]) Contains(key K) bool { return mo.index(key) >= 0 }
6✔
438

439
// Empty checks if the ordered Map is empty.
440
func (mo MapOrd[K, V]) Empty() bool { return len(mo) == 0 }
30✔
441

442
// Len returns the number of key-value pairs in the ordered Map.
443
func (mo MapOrd[K, V]) Len() Int { return Int(len(mo)) }
18✔
444

445
// Ne compares the current ordered Map to another ordered Map and returns true if they are not
446
// equal.
447
func (mo MapOrd[K, V]) Ne(other MapOrd[K, V]) bool { return !mo.Eq(other) }
8✔
448

449
// NotEmpty checks if the ordered Map is not empty.
450
func (mo MapOrd[K, V]) NotEmpty() bool { return !mo.Empty() }
2✔
451

452
// Print writes the key-value pairs of the MapOrd to the standard output (console)
453
// and returns the MapOrd unchanged.
454
func (mo MapOrd[K, V]) Print() MapOrd[K, V] { fmt.Print(mo); return mo }
1✔
455

456
// Println writes the key-value pairs of the MapOrd to the standard output (console) with a newline
457
// and returns the MapOrd unchanged.
458
func (mo MapOrd[K, V]) Println() MapOrd[K, V] { fmt.Println(mo); return mo }
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc