tags:

views:

94

answers:

1

I've got the following code:

    public IList<IProductViewModel> ChildProducts { get; set; }
    public IList<IProductViewModel> GiftItems { get; set; }
    public IList<IProductViewModel> PromoItems { get; set; }

    public IList<IProductViewModel> NonGiftItems
    {
        get
        {
            return NonPromoItems.Except(GiftItems, new ProductViewModelComparer()).ToList();
        }
    }

    public IList<IProductViewModel> NonPromoItems
    {
        get
        {
            return ChildProducts.Where(p => !p.IsPromotion).ToList();
        }
    }

ProductViewModelComparer:

public class ProductViewModelComparer : IEqualityComparer<IProductViewModel>
{

    #region IEqualityComparer<IProductViewModel> Members

    public bool Equals(IProductViewModel x, IProductViewModel y)
    {
        if (Object.ReferenceEquals(x, y))
            return true;

        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return String.Equals(x.ProductId, y.ProductId);
    }

    public int GetHashCode(IProductViewModel obj)
    {
        return obj.ProductId.GetHashCode();
    }

    #endregion
}

So basically, NonPromoItems is (ChildProducts - PromoItems) and NonGiftItems is (NonPromoItems - GiftItems)

However When:

ChildProducts = IEnumerable<IProductViewModel>[6] PromoItems = IEnumerable<IProductViewModel>[1] where item matches 1 item in ChildProducts GiftItems = IEnumerable<IProductViewModel>[0]

My Result is

NonPromoItems = IEnumerable<IProductViewModel>[5] This is Correct NonGiftItems = IEnumerable<IProductViewModel>[4] This is Incorrect

Somehow an Except(...) is removing an item when given an empty list to subtract.

Any ideas anyone?

+2  A: 

Is the removed item a duplicate of another in the list? If so, this is standard behavior for the Except method call:

The Except<T> is a little tricky in that instead of returning the difference as you might expect, it instead returns the set difference. A mathematical set does not contain duplicates (e.g. HashSet).

Here's an example of what I mean:

int[] ints = { 3, 3, 3 };
var result = ints.Except(5); // result contains one element only: { 3 } 

You can read more on this CodeProject thread in which I described the problem.

To get "Except"-like functionality while leaving duplicates, you can write the following line:

var ints = new [] { 3, 42, 3 };
var excluded = new [] { 42 };
var results = ints.Where(i => !excluded.Contains(i)); // returns { 3, 3 }
Judah Himango
Yea, it is a dupe, know if there's a way to do the same linq operation but not remove distinct entries?
Aren
Yeah, there is. I'll update my post to show an example.
Judah Himango