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

enetx / g / 18078749822

28 Sep 2025 07:21PM UTC coverage: 91.157% (-0.6%) from 91.734%
18078749822

push

github

enetx
ref mapord

196 of 254 new or added lines in 9 files covered. (77.17%)

14 existing lines in 4 files now uncovered.

6319 of 6932 relevant lines covered (91.16%)

633.24 hits per line

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

94.02
/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 comparable, V any](size ...Int) MapOrd[K, V] {
205✔
32
        return make(MapOrd[K, V], 0, Slice[Int](size).Get(0).UnwrapOrDefault())
205✔
33
}
205✔
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
// Entry returns a MapOrdEntry object for the given key, providing fine-grained
39
// control over insertion, mutation, and deletion of its value in the ordered Map,
40
// while preserving the insertion order.
41
//
42
// Example:
43
//
44
//        mo := g.NewMapOrd[string, int]()
45
//        // Insert 1 if "foo" is absent, then increment it
46
//        e := mo.Entry("foo")
47
//        e.OrSet(1).
48
//        e.Transform(func(v int) int { return v + 1 })
49
//
50
// The entire operation requires only a single key lookup and works without
51
// additional allocations.
52
func (mo *MapOrd[K, V]) Entry(key K) MapOrdEntry[K, V] { return MapOrdEntry[K, V]{mo, key} }
12✔
53

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

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

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

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

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

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

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

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

203
        return true
1✔
204
}
205

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

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

230
        return true
2✔
231
}
232

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

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

257
        return true
2✔
258
}
259

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

4✔
265
        return nmo
4✔
266
}
4✔
267

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

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

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

NEW
287
        return m
×
288
}
289

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

NEW
295
        return ms
×
296
}
297

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

8✔
305
                return Some(prev)
8✔
306
        }
8✔
307

308
        mp := Pair[K, V]{Key: key, Value: value}
465✔
309
        *mo = append(*mo, mp)
465✔
310

465✔
311
        return None[V]()
465✔
312
}
313

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

322
        return None[V]()
3✔
323
}
324

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

336
// Invert inverts the key-value pairs in the ordered Map, creating a new ordered Map with the
337
// values as keys and the original keys as values.
338
func (mo MapOrd[K, V]) Invert() MapOrd[any, K] {
2✔
339
        if mo.Empty() {
3✔
340
                return NewMapOrd[any, K]()
1✔
341
        }
1✔
342

343
        result := make(MapOrd[any, K], 0, len(mo))
1✔
344
        for _, pair := range mo {
4✔
345
                result = append(result, Pair[any, K]{Key: pair.Value, Value: pair.Key})
3✔
346
        }
3✔
347

348
        return result
1✔
349
}
350

351
func (mo MapOrd[K, V]) index(key K) int {
523✔
352
        for i, mp := range mo {
1,146✔
353
                if mp.Key == key {
671✔
354
                        return i
48✔
355
                }
48✔
356
        }
357

358
        return -1
475✔
359
}
360

361
// Keys returns an Slice containing all the keys in the ordered Map.
362
func (mo MapOrd[K, V]) Keys() Slice[K] { return mo.Iter().Keys().Collect() }
6✔
363

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

367
// Delete removes the specified keys from the ordered Map.
368
//
369
// It preserves the original insertion order of the remaining elements
370
// and performs the deletion in a single pass with O(n) complexity.
371
//
372
// Internally, it builds a set of keys to delete and reconstructs the map
373
// without the removed entries. Key lookup is optimized via a map[K]int index.
374
//
375
// Example:
376
//
377
//        mo.Delete("a", "b", "c")
378
func (mo *MapOrd[K, V]) Delete(keys ...K) {
5✔
379
        if len(keys) == 0 || mo.Empty() {
6✔
380
                return
1✔
381
        }
1✔
382

383
        idx := mo.indexMap()
4✔
384
        seen := SetOf(keys...)
4✔
385
        nmo := make(MapOrd[K, V], 0, len(*mo)-len(keys))
4✔
386

4✔
387
        for _, p := range *mo {
15✔
388
                if !seen.Contains(p.Key) {
17✔
389
                        nmo = append(nmo, p)
6✔
390
                } else {
11✔
391
                        delete(idx, p.Key)
5✔
392
                }
5✔
393
        }
394

395
        *mo = nmo
4✔
396
}
397

398
// Eq compares the current ordered Map to another ordered Map and returns true if they are equal.
399
func (mo MapOrd[K, V]) Eq(other MapOrd[K, V]) bool {
30✔
400
        if len(mo) != len(other) {
32✔
401
                return false
2✔
402
        }
2✔
403
        if len(mo) == 0 {
31✔
404
                return true
3✔
405
        }
3✔
406

407
        idx := other.indexMap()
25✔
408

25✔
409
        var zero V
25✔
410
        comparable := f.IsComparable(zero)
25✔
411

25✔
412
        for i, mp := range mo {
94✔
413
                j, ok := idx[mp.Key]
69✔
414
                if !ok || j != i {
70✔
415
                        return false
1✔
416
                }
1✔
417

418
                value := other[j].Value
68✔
419

68✔
420
                if comparable && !f.Eq[any](value)(mp.Value) || !comparable && !f.Eqd(value)(mp.Value) {
69✔
421
                        return false
1✔
422
                }
1✔
423
        }
424

425
        return true
23✔
426
}
427

428
// String returns a string representation of the ordered Map.
429
func (mo MapOrd[K, V]) String() string {
5✔
430
        if len(mo) == 0 {
6✔
431
                return "MapOrd{}"
1✔
432
        }
1✔
433

434
        var b Builder
4✔
435
        b.WriteString("MapOrd{")
4✔
436

4✔
437
        first := true
4✔
438
        for _, pair := range mo {
12✔
439
                if !first {
12✔
440
                        b.WriteString(", ")
4✔
441
                }
4✔
442

443
                first = false
8✔
444
                b.WriteString(Format("{}:{}", pair.Key, pair.Value))
8✔
445
        }
446

447
        b.WriteString("}")
4✔
448

4✔
449
        return b.String().Std()
4✔
450
}
451

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

455
// Contains checks if the ordered Map contains the specified key.
456
func (mo MapOrd[K, V]) Contains(key K) bool { return mo.index(key) != -1 }
7✔
457

458
// Empty checks if the ordered Map is empty.
459
func (mo MapOrd[K, V]) Empty() bool { return len(mo) == 0 }
13✔
460

461
// Len returns the number of key-value pairs in the ordered Map.
462
func (mo MapOrd[K, V]) Len() Int { return Int(len(mo)) }
31✔
463

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

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

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

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

478
// indexMap builds a map from keys to their corresponding indices in the MapOrd.
479
//
480
// This function is used to create a temporary indexMap that maps each key in the
481
// ordered map to its position (insertion order) within the slice. It is useful
482
// for optimizing lookup operations such as Set, Delete, Copy, or Eq.
483
//
484
// Time complexity: O(n), where n is the number of key-value pairs in the MapOrd.
485
func (mo MapOrd[K, V]) indexMap() map[K]int {
35✔
486
        idx := make(map[K]int, len(mo))
35✔
487

35✔
488
        for i, p := range mo {
123✔
489
                idx[p.Key] = i
88✔
490
        }
88✔
491

492
        return idx
35✔
493
}
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