Search code examples
c#.netlinqlambda

C# LINQ flatten array based on int property


I have a list of order items with the given structure :

OrderItem { Id = 1, Name = "First Item", Quantity = 2 }
OrderItem { Id = 2, Name = "Second Item", Quantity = 2 }
OrderItem { Id = 3, Name = "Third Item", Quantity = 1 }

I want to flatten it to the following structure :

DBItem{ Id = 1, Name = "First Item" }
DBItem{ Id = 2, Name = "First Item" }
DBItem{ Id = 3, Name = "Second Item" }
DBItem{ Id = 4, Name = "Second Item" }
DBItem{ Id = 5, Name = "Third Item" }

Is there a way using LINQ SelectMany?


Solution

  • You can use Enumerable.Range to generate aditional records:

    var dbItems = orderItems
        .OrderBy(oi => oi.Id) // ensure correct order
        .SelectMany(oi => Enumerable.Range(0, oi.Quantity), (oi, n) => oi) // records duplication
        .Select((oi, idx) => new DBItem // Select overload with index
        {
            Id = idx + 1,
            Name = oi.Name,
        })
        .ToList();