116 lines
2.1 KiB
Go
116 lines
2.1 KiB
Go
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,
|
|
"",
|
|
)
|
|
}
|