Igor Golodnitsky
Igor Golodnitsky

Reputation: 4566

How to merge several arrays in a List using Linq?

I have List<Product[]> and I need to join them into one Product[].

Upvotes: 34

Views: 25069

Answers (3)

snowcode
snowcode

Reputation: 1119

For any more complex joins IEnumerable, GetEnumerator and yield are your friends and are super performant. Just for fun, here's some code showing extending Linq with your own custom methods does not have to be scary;

public static class MyLinqExtensions
{
    public static IEnumerable<int> RoundRobin(this IEnumerable<int> a, IEnumerable<int> b)
    {
        var ae = a.GetEnumerator();
        var be = b.GetEnumerator();

        bool aHasNumber = ae.MoveNext();
        bool bHasNumber = be.MoveNext();

        while (aHasNumber || bHasNumber)
        {
            if (aHasNumber)
            {
                yield return ae.Current;
                aHasNumber = ae.MoveNext();
            }

            if (bHasNumber)
            {
                yield return be.Current;
                bHasNumber = be.MoveNext();
            }
        }
    }
}

void Main()
{

    var arr1 = new[] { 1, 2, 3, 4 };
    var arr2 = new[] { 4, 5, 6 };
    var arr3 = new[] { 7, 8, 9};
    var arr4 = new int[] {  };

    // arrays the same size
    Assert.AreEqual(new[] { 4, 7, 5, 8, 6, 9 }, arr2.RoundRobin(arr3).ToArray());

    // array 1 bigger than array 2
    Assert.AreEqual(new[] { 1, 4, 2, 5, 3, 6, 4 }, arr1.RoundRobin(arr2).ToArray());

    // array 1 smaller than 2
    Assert.AreEqual(new[] { 4, 1, 5, 2, 6, 3, 4 }, arr2.RoundRobin(arr1).ToArray());

    // 2 empty, 1 not
    Assert.AreEqual(new[] { 4, 5, 6 }, arr2.RoundRobin(new int[] { }).ToArray());

    // 1 empty, 2 not
    Assert.AreEqual(new[] { 1, 2, 3, 4 }, arr1.RoundRobin(new int[] { }).ToArray());

    // both empty
    Assert.AreEqual(new int[] {  }, arr4.RoundRobin(arr4).ToArray());

    // prove it's Linq
    Assert.AreEqual(new[] { 1, 4, 2}, arr1.RoundRobin(arr2).Take(3).ToArray());

    Console.WriteLine("pass");
}

Upvotes: 0

Marcin Deptuła
Marcin Deptuła

Reputation: 11977

You can use .Concat() extension method as well, and then .ToArray(): x.Concat(y).Concat(z).ToArray();

Upvotes: 5

Daniel Earwicker
Daniel Earwicker

Reputation: 116764

You can use SelectMany and then ToArray to do this.

var result = source.SelectMany(i => i).ToArray();

Upvotes: 85

Related Questions