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

enetx / g / 22017039949

14 Feb 2026 12:06PM UTC coverage: 89.925% (-0.9%) from 90.786%
22017039949

push

github

enetx
ref

182 of 225 new or added lines in 12 files covered. (80.89%)

30 existing lines in 7 files now uncovered.

5266 of 5856 relevant lines covered (89.92%)

14490.78 hits per line

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

90.96
/map_ordered.go
1
package g
2

3
import (
4
        "fmt"
5
        "math/rand/v2"
6
        "reflect"
7
        "slices"
8

9
        "github.com/enetx/g/cmp"
10
        "github.com/enetx/g/f"
11
        "github.com/enetx/iter"
12
)
13

14
// Pair is a struct representing a key-value Pair for MapOrd.
15
type Pair[K, V any] = iter.Pair[K, V]
16

17
// MapOrd is an ordered map that maintains insertion order using a slice for pairs
18
// and a map for fast index lookups.
19
type MapOrd[K comparable, V any] []Pair[K, V] // ordered key-value pairs
20

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

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

47
// Entry returns an OrdEntry for the given key.
48
func (mo *MapOrd[K, V]) Entry(key K) OrdEntry[K, V] {
45✔
49
        if i := mo.index(key); i != -1 {
66✔
50
                return OccupiedOrdEntry[K, V]{mo: mo, key: key, index: i}
21✔
51
        }
21✔
52

53
        return VacantOrdEntry[K, V]{mo: mo, key: key}
24✔
54
}
55

56
// Iter returns an iterator (SeqMapOrd[K, V]) for the ordered Map, allowing for sequential iteration
57
// over its key-value pairs. It is commonly used in combination with higher-order functions,
58
// such as 'ForEach', to perform operations on each key-value pair of the ordered Map.
59
//
60
// Returns:
61
//
62
// A SeqMapOrd[K, V], which can be used for sequential iteration over the key-value pairs of the ordered Map.
63
//
64
// Example usage:
65
//
66
//        m := g.NewMapOrd[int, int]()
67
//        m.Set(1, 1)
68
//        m.Set(2, 2)
69
//        m.Set(3, 3).
70
//
71
//        m.Iter().ForEach(func(k, v int) {
72
//            // Process key-value pair
73
//        })
74
//
75
// The 'Iter' method provides a convenient way to traverse the key-value pairs of an ordered Map
76
// in a functional style, enabling operations like mapping or filtering.
77
func (mo MapOrd[K, V]) Iter() SeqMapOrd[K, V] {
79✔
78
        return func(yield func(K, V) bool) {
163✔
79
                for _, v := range mo {
288✔
80
                        if !yield(v.Key, v.Value) {
221✔
81
                                return
17✔
82
                        }
17✔
83
                }
84
        }
85
}
86

87
// IterReverse returns an iterator (SeqMapOrd[K, V]) for the ordered Map that allows for sequential iteration
88
// over its key-value pairs in reverse order. This method is useful when you need to process the elements
89
// from the last to the first.
90
//
91
// Returns:
92
//
93
// A SeqMapOrd[K, V], which can be used for sequential iteration over the key-value pairs of the ordered Map in reverse order.
94
//
95
// Example usage:
96
//
97
//        m := g.NewMapOrd[int, int]()
98
//        m.Set(1, 1)
99
//        m.Set(2, 2)
100
//        m.Set(3, 3)
101
//
102
//        m.IterReverse().ForEach(func(k, v int) {
103
//            // Process key-value pair in reverse order
104
//            fmt.Println("Key:", k, "Value:", v)
105
//        })
106
//
107
// The 'IterReverse' method complements the 'Iter' method by providing a way to access the elements
108
// in a reverse sequence, offering additional flexibility in data processing scenarios.
109
func (mo MapOrd[K, V]) IterReverse() SeqMapOrd[K, V] {
4✔
110
        return func(yield func(K, V) bool) {
8✔
111
                for i := len(mo) - 1; i >= 0; i-- {
8✔
112
                        v := mo[i]
4✔
113
                        if !yield(v.Key, v.Value) {
4✔
114
                                return
×
115
                        }
×
116
                }
117
        }
118
}
119

120
// MapOrdFromStd converts a standard Go map to an ordered Map.
121
// The resulting ordered Map will maintain the order of its key-value pairs based on the order of
122
// insertion.
123
// This function is useful when you want to create an ordered Map from an existing Go map.
124
//
125
// Parameters:
126
//
127
// - m map[K]V: The input Go map to be converted to an ordered Map.
128
//
129
// Returns:
130
//
131
// - MapOrd[K, V]: New ordered Map containing the same key-value pairs as the
132
// input Go map.
133
//
134
// Example usage:
135
//
136
//        mapOrd := g.MapOrdFromStd[string, int](goMap)
137
//
138
// Converts the standard Go map 'map[K]V' to an ordered Map.
139
func MapOrdFromStd[K comparable, V any](m map[K]V) MapOrd[K, V] { return Map[K, V](m).Ordered() }
2✔
140

141
// SortBy sorts the ordered Map by a custom comparison function.
142
//
143
// Parameters:
144
//
145
// - fn func(a, b Pair[K, V]) cmp.Ordering: The custom comparison function used for sorting the ordered Map.
146
//
147
// Example usage:
148
//
149
//        hmapo.SortBy(func(a, b g.Pair[g.String, g.Int]) cmp.Ordering { return a.Key.Cmp(b.Key) })
150
//        hmapo.SortBy(func(a, b g.Pair[g.String, g.Int]) cmp.Ordering { return a.Value.Cmp(b.Value) })
151
func (mo MapOrd[K, V]) SortBy(fn func(a, b Pair[K, V]) cmp.Ordering) {
3✔
152
        slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a, b)) })
11✔
153
}
154

155
// SortByKey sorts the ordered MapOrd[K, V] by the keys using a custom comparison function.
156
//
157
// Parameters:
158
//
159
// - fn func(a, b K) cmp.Ordering: The custom comparison function used for sorting the keys.
160
//
161
// Example usage:
162
//
163
//        hmapo.SortByKey(func(a, b g.String) cmp.Ordering { return a.Cmp(b) })
164
func (mo MapOrd[K, V]) SortByKey(fn func(a, b K) cmp.Ordering) {
6✔
165
        slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a.Key, b.Key)) })
35✔
166
}
167

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

181
// IsSortedBy checks if the ordered Map is sorted according to a custom comparison function.
182
//
183
// Parameters:
184
//
185
// - fn func(a, b Pair[K, V]) cmp.Ordering: The custom comparison function used for checking sort order.
186
//
187
// Returns:
188
//
189
// - bool: true if the map is sorted according to the comparison function, false otherwise.
190
//
191
// Example usage:
192
//
193
//        sorted := hmapo.IsSortedBy(func(a, b g.Pair[g.String, g.Int]) cmp.Ordering { return a.Key.Cmp(b.Key) })
194
func (mo MapOrd[K, V]) IsSortedBy(fn func(a, b Pair[K, V]) cmp.Ordering) bool {
4✔
195
        if len(mo) <= 1 {
6✔
196
                return true
2✔
197
        }
2✔
198

199
        for i := 1; i < len(mo); i++ {
5✔
200
                if fn(mo[i-1], mo[i]).IsGt() {
4✔
201
                        return false
1✔
202
                }
1✔
203
        }
204

205
        return true
1✔
206
}
207

208
// IsSortedByKey checks if the ordered MapOrd[K, V] is sorted by the keys using a custom comparison function.
209
//
210
// Parameters:
211
//
212
// - fn func(a, b K) cmp.Ordering: The custom comparison function used for checking key sort order.
213
//
214
// Returns:
215
//
216
// - bool: true if the map is sorted by keys according to the comparison function, false otherwise.
217
//
218
// Example usage:
219
//
220
//        sorted := hmapo.IsSortedByKey(func(a, b g.String) cmp.Ordering { return a.Cmp(b) })
221
func (mo MapOrd[K, V]) IsSortedByKey(fn func(a, b K) cmp.Ordering) bool {
6✔
222
        if len(mo) <= 1 {
8✔
223
                return true
2✔
224
        }
2✔
225

226
        for i := 1; i < len(mo); i++ {
10✔
227
                if fn(mo[i-1].Key, mo[i].Key).IsGt() {
8✔
228
                        return false
2✔
229
                }
2✔
230
        }
231

232
        return true
2✔
233
}
234

235
// IsSortedByValue checks if the ordered MapOrd[K, V] is sorted by the values using a custom comparison function.
236
//
237
// Parameters:
238
//
239
// - fn func(a, b V) cmp.Ordering: The custom comparison function used for checking value sort order.
240
//
241
// Returns:
242
//
243
// - bool: true if the map is sorted by values according to the comparison function, false otherwise.
244
//
245
// Example usage:
246
//
247
//        sorted := hmapo.IsSortedByValue(func(a, b g.Int) cmp.Ordering { return a.Cmp(b) })
248
func (mo MapOrd[K, V]) IsSortedByValue(fn func(a, b V) cmp.Ordering) bool {
6✔
249
        if len(mo) <= 1 {
8✔
250
                return true
2✔
251
        }
2✔
252

253
        for i := 1; i < len(mo); i++ {
10✔
254
                if fn(mo[i-1].Value, mo[i].Value).IsGt() {
8✔
255
                        return false
2✔
256
                }
2✔
257
        }
258

259
        return true
2✔
260
}
261

262
// Clone creates a new ordered Map with the same key-value pairs.
263
func (mo MapOrd[K, V]) Clone() MapOrd[K, V] {
4✔
264
        nmo := NewMapOrd[K, V](mo.Len())
4✔
265
        nmo.Copy(mo)
4✔
266

4✔
267
        return nmo
4✔
268
}
4✔
269

270
// Copy copies key-value pairs from the source ordered Map to the current ordered Map.
271
func (mo *MapOrd[K, V]) Copy(src MapOrd[K, V]) {
6✔
272
        idx := mo.indexMap()
6✔
273

6✔
274
        for _, p := range src {
18✔
275
                if i, ok := idx[p.Key]; ok {
12✔
276
                        (*mo)[i].Value = p.Value
×
277
                } else {
12✔
278
                        *mo = append(*mo, p)
12✔
279
                        idx[p.Key] = len(*mo) - 1
12✔
280
                }
12✔
281
        }
282
}
283

284
// Map converts the ordered Map to a standard Map.
285
func (mo MapOrd[K, V]) Map() Map[K, V] {
×
286
        m := NewMap[K, V](mo.Len())
×
287
        mo.Iter().ForEach(func(k K, v V) { m[k] = v })
×
288

289
        return m
×
290
}
291

292
// Safe converts a ordered Map to a thread-safe Map.
293
func (mo MapOrd[K, V]) Safe() *MapSafe[K, V] {
×
294
        ms := NewMapSafe[K, V]()
×
295
        mo.Iter().ForEach(func(k K, v V) { ms.Insert(k, v) })
×
296

297
        return ms
×
298
}
299

300
// Insert sets the value for the specified key in the ordered Map,
301
// and returns the previous value if it existed.
302
func (mo *MapOrd[K, V]) Insert(key K, value V) Option[V] {
461✔
303
        if i := mo.index(key); i != -1 {
469✔
304
                prev := (*mo)[i].Value
8✔
305
                (*mo)[i].Value = value
8✔
306

8✔
307
                return Some(prev)
8✔
308
        }
8✔
309

310
        mp := Pair[K, V]{Key: key, Value: value}
453✔
311
        *mo = append(*mo, mp)
453✔
312

453✔
313
        return None[V]()
453✔
314
}
315

316
// Get returns the value associated with the given key, wrapped in Option[V].
317
//
318
// It returns Some(value) if the key exists, or None if it does not.
319
func (mo MapOrd[K, V]) Get(key K) Option[V] {
37✔
320
        if i := mo.index(key); i != -1 {
74✔
321
                return Some(mo[i].Value)
37✔
322
        }
37✔
323

324
        return None[V]()
×
325
}
326

327
// Shuffle randomly reorders the elements of the ordered Map.
328
// It operates in place and affects the original order of the map's entries.
329
//
330
// The function uses the crypto/rand package to generate random indices.
331
func (mo MapOrd[K, V]) Shuffle() {
1✔
332
        for i := mo.Len() - 1; i > 0; i-- {
5✔
333
                j := rand.N(i + 1)
4✔
334
                mo[i], mo[j] = mo[j], mo[i]
4✔
335
        }
4✔
336
}
337

338
func (mo MapOrd[K, V]) index(key K) int {
549✔
339
        for i, mp := range mo {
1,208✔
340
                if mp.Key == key {
728✔
341
                        return i
69✔
342
                }
69✔
343
        }
344

345
        return -1
480✔
346
}
347

348
// Keys returns an Slice containing all the keys in the ordered Map.
349
func (mo MapOrd[K, V]) Keys() Slice[K] { return mo.Iter().Keys().Collect() }
9✔
350

351
// Values returns an Slice containing all the values in the ordered Map.
352
func (mo MapOrd[K, V]) Values() Slice[V] { return mo.Iter().Values().Collect() }
2✔
353

354
// Remove removes the specified key from the ordered Map and returns the removed value.
355
func (mo *MapOrd[K, V]) Remove(key K) Option[V] {
7✔
356
        if mo.IsEmpty() {
8✔
357
                return None[V]()
1✔
358
        }
1✔
359

360
        for i, p := range *mo {
17✔
361
                if p.Key == key {
16✔
362
                        *mo = append((*mo)[:i], (*mo)[i+1:]...)
5✔
363
                        return Some(p.Value)
5✔
364
                }
5✔
365
        }
366

367
        return None[V]()
1✔
368
}
369

370
// Eq compares the current ordered Map to another ordered Map and returns true if they are equal.
371
func (mo MapOrd[K, V]) Eq(other MapOrd[K, V]) bool {
30✔
372
        if len(mo) != len(other) {
32✔
373
                return false
2✔
374
        }
2✔
375
        if len(mo) == 0 {
31✔
376
                return true
3✔
377
        }
3✔
378

379
        idx := other.indexMap()
25✔
380

25✔
381
        comparable := f.IsComparable[V]()
25✔
382
        for i, mp := range mo {
94✔
383
                j, ok := idx[mp.Key]
69✔
384

69✔
385
                if !ok || j != i {
70✔
386
                        return false
1✔
387
                }
1✔
388

389
                if comparable {
136✔
390
                        if any(other[j].Value) != any(mp.Value) {
69✔
391
                                return false
1✔
392
                        }
1✔
NEW
393
                } else {
×
NEW
394
                        if !reflect.DeepEqual(other[j].Value, mp.Value) {
×
NEW
395
                                return false
×
NEW
396
                        }
×
397
                }
398
        }
399

400
        return true
23✔
401
}
402

403
// String returns a string representation of the ordered Map.
404
func (mo MapOrd[K, V]) String() string {
5✔
405
        if len(mo) == 0 {
6✔
406
                return "MapOrd{}"
1✔
407
        }
1✔
408

409
        var b Builder
4✔
410
        b.WriteString("MapOrd{")
4✔
411

4✔
412
        first := true
4✔
413
        for _, pair := range mo {
12✔
414
                if !first {
12✔
415
                        b.WriteString(", ")
4✔
416
                }
4✔
417

418
                first = false
8✔
419
                fmt.Fprint(&b, pair.Key)
8✔
420
                b.WriteByte(':')
8✔
421
                fmt.Fprint(&b, pair.Value)
8✔
422
        }
423

424
        b.WriteString("}")
4✔
425

4✔
426
        return b.String().Std()
4✔
427
}
428

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

432
// Contains checks if the ordered Map contains the specified key.
433
func (mo MapOrd[K, V]) Contains(key K) bool { return mo.index(key) != -1 }
6✔
434

435
// Empty checks if the ordered Map is empty.
436
func (mo MapOrd[K, V]) IsEmpty() bool { return len(mo) == 0 }
11✔
437

438
// Len returns the number of key-value pairs in the ordered Map.
439
func (mo MapOrd[K, V]) Len() Int { return Int(len(mo)) }
26✔
440

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

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

448
// Println writes the key-value pairs of the MapOrd to the standard output (console) with a newline
449
// and returns the MapOrd unchanged.
450
func (mo MapOrd[K, V]) Println() MapOrd[K, V] { fmt.Println(mo); return mo }
1✔
451

452
// indexMap builds a map from keys to their corresponding indices in the MapOrd.
453
//
454
// This function is used to create a temporary indexMap that maps each key in the
455
// ordered map to its position (insertion order) within the slice. It is useful
456
// for optimizing lookup operations such as Set, Delete, Copy, or Eq.
457
//
458
// Time complexity: O(n), where n is the number of key-value pairs in the MapOrd.
459
func (mo MapOrd[K, V]) indexMap() map[K]int {
31✔
460
        idx := make(map[K]int, len(mo))
31✔
461

31✔
462
        for i, p := range mo {
108✔
463
                idx[p.Key] = i
77✔
464
        }
77✔
465

466
        return idx
31✔
467
}
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