-
Notifications
You must be signed in to change notification settings - Fork 8
/
map_string_slice.go
133 lines (117 loc) · 3.38 KB
/
map_string_slice.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package maputil
import (
"net/url"
"sort"
"strings"
"github.com/grokify/mogo/type/slicesutil"
"github.com/grokify/mogo/type/stringsutil"
)
// type MapStringSlice map[string][]string
type MapStringSlice url.Values
func NewMapStringSlice() MapStringSlice {
return MapStringSlice{}
}
// Add adds a key and value to the `map[string][]string`. It will
// panic on a nil struct, so do not precede with `var mss MapStringSlice`
func (mss MapStringSlice) Add(key, value string) {
if _, ok := mss[key]; !ok {
mss[key] = []string{value}
} else {
mss[key] = append(mss[key], value)
}
}
func (mss MapStringSlice) Clone() MapStringSlice {
new := url.Values{}
for k, vals := range mss {
for _, v := range vals {
new.Add(k, v)
}
}
return MapStringSlice(new)
}
func (mss MapStringSlice) Sort(dedupe bool) {
for key, vals := range mss {
if dedupe {
vals = slicesutil.Dedupe(vals)
}
sort.Strings(vals)
mss[key] = vals
}
}
func (mss MapStringSlice) Keys() []string {
return StringKeys(mss, nil)
}
// KeysByValueCounts returns a `map[int][]string` where the key is the
// count of values and the values are the keys with that value count.
func (mss MapStringSlice) KeysByValueCounts() map[int][]string {
byCount := map[int][]string{}
for key, vals := range mss {
count := len(vals)
byCount[count] = append(byCount[count], key)
}
return byCount
}
// CondenseSpace will trim spaces for keys and values, and remove empty values. It will
// also optionally dedupe and sort values.
func (mss MapStringSlice) CondenseSpace(dedupeVals, sortVals bool) map[string][]string {
// func MapStringSliceCondenseSpace(m map[string][]string, dedupeVals, sortVals bool) map[string][]string {
new := map[string][]string{}
for key, vals := range mss {
new[strings.TrimSpace(key)] = stringsutil.SliceCondenseSpace(vals, dedupeVals, sortVals)
}
return new
}
func KeyValueSliceCounts[K comparable, V any](m map[K][]V) map[K]int {
r := map[K]int{}
for k, vals := range m {
r[k] = len(vals)
}
return r
}
// Flatten converts a `map[string][]string{}` to a `map[string]string{}`. The default is to use the first value
// unless `useLast` is set to true, in which case the last value is used. The default is to use a key with an
// empty string to represent a key with an empty slice, unless `skipEmpty` is set to `true`, in which case the
// key with an empty slice is not represented.
func (mss MapStringSlice) Flatten(useLast, skipEmpty bool) map[string]string {
simple := map[string]string{}
for k, vals := range mss {
if len(vals) == 0 {
if !skipEmpty {
simple[k] = ""
}
} else if useLast {
simple[k] = vals[len(vals)-1]
} else {
simple[k] = vals[0]
}
}
return simple
}
// FlattenAny converts the results of `Flatten()` to a `map[string]any{}`.`
func (mss MapStringSlice) FlattenAny(useLast, skipEmpty bool) map[string]any {
msa := map[string]any{}
mssimple := mss.Flatten(useLast, skipEmpty)
for k, v := range mssimple {
msa[k] = v
}
return msa
}
func (mss MapStringSlice) Lines(m map[string][]string, keyPrefix, valPrefix string) []string {
var lines []string
for k, vals := range mss {
lines = append(lines, keyPrefix+k)
for _, v := range vals {
lines = append(lines, valPrefix+v)
}
}
return lines
}
func (mss MapStringSlice) ReveseFlatten() map[string]string {
out := map[string]string{}
for k, vals := range mss {
for _, v := range vals {
out[v] = k
}
}
return out
}