0

I have a situation where I need to iterate through a collection and add another collection to one of its member using Linq.

For example I have this class

public class Product
{
    public string Car { get; set; }
    public IEnumerable<Part> Part { get; set; }
}

This class would be within a collection like

IEnumerable<Product> ProductList

How can I populate the Part-property for each Product using GetPartData() with Linq

private IEnumerable<IEnumerable<Part>> GetPartData()
{
    return new List<List<Part>>() { 
        new List<Part>{
            new Part(){PartType="11",PartValue=1},
            new Part(){PartType="12",PartValue=2}
        },
        new List<Part>{
            new Part(){PartType="21",PartValue=1},
            new Part(){PartType="22",PartValue=2}
        }
    };
}

So ultimately, my ProductList[0].Part should be equal to GetPartData()[0]

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
Frenz
  • 687
  • 1
  • 10
  • 22

2 Answers2

1

If both sequences should be linked via index you can use Enumerable.Zip:

ProductList = ProductList.Zip(GetPartData()
    , (product, part) => new Product
    {
        Car = product.Car,
        Part = part
    })
.ToList();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Thank you @tim-schmelter. Considering the fact that I would have a lot of properties apart from "part". Is there a better way to do it or else do I have to map each properties. How will I need to refine it if I can use Auto Mapper. – Frenz Jul 01 '15 at 12:20
0

Basically, you need to enumerate two IEnumerable at a time to match items from both. The ProductList and the result of GetPartData.

// The two IEnumerable
var products = ProductList;
var parts = GetPartData();

foreach((product, part) in (products, parts))  // will not work :(
{
    product.Part = part;
}

Solutions has been debated before.

The Zip method will do it.

// The two IEnumerable
var products = ProductList;
var parts = GetPartData();

products.Zip(parts, (product, part) => product.Part = part).ToList();

The ToList() is really important, to force the execution.

If you are not comfortable with the lambda, you can do it like this:

// The two IEnumerable
var products = ProductList;
var parts = GetPartData();

products.Zip(parts, ProductPartAssociation).ToList();

...

Product ProductPartAssociation(Product product, IEnumerable<Part> part)
{
   product.Part = part;
   return product;      // Actually not used.
}

The result of the Zip is an IEnumerable of whatever the ProductPartAssociation function return. You don't care about it, because what you need is just to be sure that the ProductPartAssociation is executed.

Community
  • 1
  • 1
Orace
  • 7,822
  • 30
  • 45