简体   繁体   中英

Linq get combinations of two lists

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM