Reputation: 3086
Say I have a sentence with multiple variables as follows:
"lorem ipsum {a, b} dolor {c, d, e} sit amet"
Assuming the letters in the braces are variables, how would one go about generating a group of sentences out of all possible combinations of the variables?
Note: The number of variable groups or variable count within each group of variables is unknown.
The expected output for this particular example would be:
"lorem ipsum {a} dolor {c} sit amet"
"lorem ipsum {b} dolor {c} sit amet"
"lorem ipsum {a} dolor {d} sit amet"
"lorem ipsum {b} dolor {d} sit amet"
"lorem ipsum {a} dolor {e} sit amet"
"lorem ipsum {b} dolor {e} sit amet"
Upvotes: 3
Views: 253
Reputation: 186813
In general case ("number of variable groups... count within each group ... is unknown") we should parse the initial string (let's do it with a help of regular expressions) and then enumerate all the combinations.
C# Code:
using System.Text.RegularExpressions;
...
private static IEnumerable<string> Generator(string source) {
// parsing: variables extracted: array of variables and their possible values
string[][] variables = Regex
.Matches(source, @"\{.*?\}")
.OfType<Match>()
.Select(match => match
.Value
.Trim('{', '}')
.Split(',')
.Select(item => "{" + item.Trim() + "}")
.ToArray())
.ToArray();
// now we should enumerate all possible variables' values
int[] indexes = new int[variables.Length];
do {
// code golf : ugly side effects but short code
int at = 0;
yield return Regex.Replace(source, @"\{.*?\}", match => variables[at][indexes[at++]]);
for (int i = 0; i < indexes.Length; ++i)
if (indexes[i] < variables[i].Length - 1) {
indexes[i] = indexes[i] + 1;
break;
}
else
indexes[i] = 0;
}
while (!indexes.All(index => index == 0));
}
Demo:
string source = @"lorem ipsum {a, b} dolor {c, d, e} sit amet";
string report = string.Join(Environment.NewLine, Generator(source));
Console.Write(report);
Outcome:
lorem ipsum {a} dolor {c} sit amet
lorem ipsum {b} dolor {c} sit amet
lorem ipsum {a} dolor {d} sit amet
lorem ipsum {b} dolor {d} sit amet
lorem ipsum {a} dolor {e} sit amet
lorem ipsum {b} dolor {e} sit amet
Another example:
// 3 groups of variables with strange names
string source = @"lorem ipsum {A + 2, B, C?} dolor {XY, PQR} sit {eh?, bla-bla-bla} amet";
Console.Write(string.Join(Environment.NewLine, Generator(source)));
Outcome:
lorem ipsum {A + 2} dolor {XY} sit {eh?} amet
lorem ipsum {B} dolor {XY} sit {eh?} amet
lorem ipsum {C?} dolor {XY} sit {eh?} amet
lorem ipsum {A + 2} dolor {PQR} sit {eh?} amet
lorem ipsum {B} dolor {PQR} sit {eh?} amet
lorem ipsum {C?} dolor {PQR} sit {eh?} amet
lorem ipsum {A + 2} dolor {XY} sit {bla-bla-bla} amet
lorem ipsum {B} dolor {XY} sit {bla-bla-bla} amet
lorem ipsum {C?} dolor {XY} sit {bla-bla-bla} amet
lorem ipsum {A + 2} dolor {PQR} sit {bla-bla-bla} amet
lorem ipsum {B} dolor {PQR} sit {bla-bla-bla} amet
lorem ipsum {C?} dolor {PQR} sit {bla-bla-bla} amet
Upvotes: 2
Reputation: 82514
So basically you want to iterate two different arrays for all possible combinations of a single value from each array - Nested loops is probably the best option.
Here's a c# code to do that, with comments on each line for easy translation to other languages:
var values0 = new string[] {"a", "b"}; // All possible values for first slot
var values1 = new string[] {"c", "d", "e"}; // All possible values for second slot
foreach(var val0 in values0) // Iterate first array
{
foreach(var val1 in values1) // Iterate second array
{
var result = $"Lorem ipsum {val0} dolor {val1} sit amet"; // Insert values to slots
Console.WriteLine(str); // output
}
}
Result:
Lorem ipsum a dolor c sit amet
Lorem ipsum a dolor d sit amet
Lorem ipsum a dolor e sit amet
Lorem ipsum b dolor c sit amet
Lorem ipsum b dolor d sit amet
Lorem ipsum b dolor e sit amet
Upvotes: 1