Suppose I have these two arrays
var a = new[] { "a", "b" };
var b = new[] { "1", "2", "3" };
I'm looking for a clever way (using linq or a custom linq extension method) to produce this set of results:
a b 1 2 3
a 1 b 2 3
1 a b 2 3
a 1 2 b 3
1 a 2 b 3
1 2 a b 3
a 1 2 3 b
1 a 2 3 b
1 2 a 3 b
1 2 3 a b
So I'd like to produce all the possible concatenations of fragments of both arrays without changing the order within the fragments.
Does anybody have a good idea how to implement this, maybe by using a recursive approach?
Thanks!
Here's an elegant (but not efficient) recursive solution:
static IEnumerable<IEnumerable<T>> Interleave<T>(T[] a, T[] b)
{
if (a.Length == 0)
{
yield return b;
}
else if (b.Length == 0)
{
yield return a;
}
else
{
foreach (var rest in Interleave(a[1..], b))
{
yield return Enumerable.Concat(new[] { a[0] }, rest);
}
foreach (var rest in Interleave(a, b[1..]))
{
yield return Enumerable.Concat(new[] { b[0] }, rest);
}
}
}
You can run it here .
Based on the work of @brianberns (thanks!) I created this method which seems to be a bit faster:
public static IEnumerable<T[]> Interleave<T>(T[] input1, T[] input2)
{
if (input1.Length == 0)
{
yield return input2;
}
else if (input2.Length == 0)
{
yield return input1;
}
else
{
foreach (var rest in Interleave(input1[1..], input2))
{
yield return new_arr(input1[0], rest);
}
foreach (var rest in Interleave(input1, input2[1..]))
{
yield return new_arr(input2[0], rest);
}
}
//local method..
static T[] new_arr(T left, T[] right)
{
var arr = new T[1 + right.Length];
arr[0] = left;
right.CopyTo(arr, 1);
return arr;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.