niklr
niklr

Reputation: 1701

Concat multiple IEnumerables with constraint

I have an object with multiple Offers assigned through different ways. An Offer is exactly for one Product and an object has multiple Offers. Now I want all Offers of an object following a specifig business logic that a Product is contained only once.

At the moment I have implemented it as follows:

List<Offer> offers = new List<Offer>();
List<Product> products = new List<Product>();                
this.AddOffersToList(offers, products, ov.Offers.Where(o => o.OfferType == composedOffer));
this.AddOffersToList(offers, products, ov.Offers.Where(o => o.OfferType == simpleOffer));
this.AddOffersToList(offers, products, ov.ComposedOfferList.Offers);
this.AddOffersToList(offers, products, ov.SimpleOfferList.Offers);

AddOffersToList method:

private void AddOffersToList(List<Offer> offers, List<Product> products,IEnumerable<Offer> newOffers)
{
    foreach (Offer offer in newOffers)
    {
        // add offer only if the product is not contained yet
        if (!products.Contains(offer.Product))
        {
            offers.Add(offer);
            products.Add(offer.Product);
        } 
    }
}

This seems to be not the most elegant and performance way. The "constraints" are the order of AddOffersToList method calls and that the Product is contained once only.

Anything that helps me solve this problem better is very welcome!

Upvotes: 2

Views: 155

Answers (1)

Timothy Shields
Timothy Shields

Reputation: 79531

This code is 'equivalent' to what you have I believe.

var offers = ov.Offers.Where(o => o.OfferType == composedOffer)
    .Concat(ov.Offers.Where(o => o.OfferType == simpleOffer))
    .Concat(ov.ComposedOfferList.Offers)
    .Concat(ov.SimpleOfferList.Offers)
    .GroupBy(offer => offer.Product)
    .Select(group => group.First())
    .ToList();

var products = offers.Select(offer => offer.Product).ToList();

Upvotes: 1

Related Questions