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
|
package interactors
import (
"regexp"
"sort"
"strings"
)
type simpleSet map[string]bool
var unicode = regexp.MustCompile("[^\x00-\x7F]+")
func (s simpleSet) Contains(other string) bool {
enabled, exists := s[other]
return exists && enabled
}
// Returns the different of two slices of strings; effectively a set arithmetic operation on two slices of strings
func DistinctValues(slice1, slice2 []string) []string {
sets := []simpleSet{
sliceToSimpleSet(slice1),
sliceToSimpleSet(slice2),
}
discardKeysFromOther(sets[0], sets[1])
discardKeysFromOther(sets[1], sets[0])
var exclusiveValues []string
for _, k := range allKeys(sets...) {
for _, set := range sets {
if set[k] == true {
exclusiveValues = append(exclusiveValues, k)
}
}
}
sort.Strings(exclusiveValues)
return exclusiveValues
}
func SetSubtract(add, negate []string) []string {
toRemove := sliceToSimpleSet(negate)
var result []string
for _, a := range add {
if !toRemove.Contains(a) {
result = append(result, a)
}
}
return result
}
func SetUnion(slice1, slice2 []string) []string {
union := allKeys(
sliceToSimpleSet(
append(
slice1,
slice2...,
),
),
)
sort.Strings(union)
return union
}
func sliceToSimpleSet(s []string) simpleSet {
m := make(simpleSet, len(s))
for _, val := range s {
m[val] = true
}
return m
}
func discardKeysFromOther(s1, s2 simpleSet) {
for k := range s1 {
if _, exists := s2[k]; exists {
s2[k] = false
}
}
}
func allKeys(sets ...simpleSet) []string {
totalCount := 0
for _, s := range sets {
totalCount += len(s)
}
keys := make([]string, totalCount)
index := 0
for _, s := range sets {
for k := range s {
keys[index] = k
index++
}
}
return keys
}
func FilterNoUnicode(s string) string {
badCharacters := sliceToSimpleSet(
unicode.FindAllString(s, -1),
)
if len(badCharacters) == 0 {
return s
}
validCharacters := make([]string, 0, len(s))
for _, rune_ := range s {
char := string(rune_)
if !badCharacters.Contains(char) {
validCharacters = append(validCharacters, char)
}
}
return strings.Join(
validCharacters,
"",
)
}
|