Skip to content

Commit

Permalink
fix: prevent endless loop for specific case. Also rewrite from recurs…
Browse files Browse the repository at this point in the history
…ive to imperative function.
  • Loading branch information
rkettelerij committed Jan 10, 2025
1 parent 138b2e0 commit fba8cdc
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions internal/etl/transform/subst_and_synonyms.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ func (s SubstAndSynonyms) generate(fieldValuesByName map[string]string) []map[st
// Create map with for each key a slice of []values
fieldValuesByNameWithAllValues[key] = allValues
}
return generateAllCombinations(fieldValuesByNameWithAllValues)
combinations := generateAllCombinations(fieldValuesByNameWithAllValues)
return combinations
}

// Transform a map[string][]string into a []map[string]string using the cartesian product, i.e.
Expand Down Expand Up @@ -82,19 +83,26 @@ func generateCombinations(keys []string, values [][]string) []map[string]string

func extendValues(input []string, mapping map[string]string) []string {
var results []string
results = append(results, input...)

for j := range input {
for len(input) > 0 {
// Pop the first element from the input slice
current := input[0]
input = input[1:]

// Add the current string to the results
results = append(results, current)

// Generate new strings based on the mapping
for oldChar, newChar := range mapping {
if strings.Contains(input[j], oldChar) {
for i := 0; i < strings.Count(input[j], oldChar); i++ {
extendedInput := replaceNth(input[j], oldChar, newChar, i+1)
subCombinations := extendValues([]string{extendedInput}, mapping)
results = append(results, subCombinations...)
if strings.Contains(current, oldChar) {
for i := 0; i < strings.Count(current, oldChar); i++ {
extendedInput := replaceNth(current, oldChar, newChar, i+1)
input = append(input, extendedInput)
}
}
}
}

// Possible performance improvement here by avoiding duplicates in the first place
return uniqueSlice(results)
}
Expand All @@ -105,6 +113,11 @@ func replaceNth(input, oldChar, newChar string, nthIndex int) string {

for i := 0; i < len(input); i++ {
if strings.HasPrefix(input[i:], oldChar) {
if strings.HasPrefix(newChar, oldChar) {
// skip to prevent endless loop (in calling function) for cases such as
// oldChar = "foo", newChar = "foos" and input = "foosball", which would otherwise result in "foosssssssssssssssball"
continue
}
count++
if count == nthIndex {
result.WriteString(newChar)
Expand Down

0 comments on commit fba8cdc

Please sign in to comment.