Well, it probably isn't how I'd write it, but:
static IEnumerable<T[]> Permute<T>(this T[] xs, params T[] pre) {
if (xs.Length == 0) yield return pre;
for (int i = 0; i < xs.Length; i++) {
foreach (T[] y in Permute(xs.Take(i).Union(xs.Skip(i+1)).ToArray(), pre.Union(new[] { xs[i] }).ToArray())) {
yield return y;
}
}
}
Re your comment; I'm not entirely clear on the question; if you mean "why is this useful?" - among other things, there are a range of brute-force scenarios where you would want to try different permutations - for example, for small ordering problems like travelling sales person (that aren't big enough to warrant a more sophisticated solution), you might want to check whether it is best to go {base,A,B,C,base}, {base,A,C,B,base},{base,B,A,C,base}, etc.
If you mean "how would I use this method?" - untested, but something like:
int[] values = {1,2,3};
foreach(int[] perm in values.Permute()) {
WriteArray(perm);
}
void WriteArray<T>(T[] values) {
StringBuilder sb = new StringBuilder();
foreach(T value in values) {
sb.Append(value).Append(", ");
}
Console.WriteLine(sb);
}
If you mean "how does it work?" - iterator blocks (yield return
) are a complex subject in themselves - Jon has a free chapter (6) in his book, though. The rest of the code is very much like your original question - just using LINQ to provide the moral equivalent of +
(for arrays).