1

I have two lists and they are named: currentItems and newItems. newItems contains items found in currentItems and I am trying to those items before I output the list.

I have done some searching and I have tried using:

var newList = newItems.Except(CurrentItems).ToList();

but when I look at the output I still find the items from currentItems in the list. I found this example when I came across this question:

Quickest way to compare two List<>

which is similar to what I am trying to achieve but the all answers to the question do not work for me.

I have tried using:

List<ListItem> newList = newItems.Union(CurrentItems).ToList();

but I believe I am using it in the wrong situation since I am trying to remove the item completely from the list.

I have also tried looping through both loops, but I don't believe that is as efficient as it can be.

In the first example is there something I may be doing wrong with it? Or is there a different way to achieve my goal?

Community
  • 1
  • 1
Joe W
  • 1,567
  • 6
  • 23
  • 36
  • What do your lists consist of? – System Down Dec 09 '13 at 19:53
  • 1
    What are `ListItems`? Is equality properly defined for them? Look at [this answer](http://stackoverflow.com/questions/19883357/trying-to-implement-a-method-that-can-compare-any-two-lists-but-it-always-return/19883434#19883434). – BartoszKP Dec 09 '13 at 19:53
  • 6
    Do the items in your list implement .GetHashCode and .Equals? Your `Except()` based solution should work... – John Gibb Dec 09 '13 at 19:54
  • My lists consists of sku value, which is an alpha/numeric string that is unique to each item. The text of the list is the sku and item description, which is where the two lists differ, the lists have different item descriptions but identical sku values. – Joe W Dec 09 '13 at 20:10

1 Answers1

2

IEnumerable.Except will do what you want but it uses the default equality comparer. For custom objects you will need to implement Equals and GetHashCode

Also note that if newItems has duplicate values IEnumerable.Except will also do a distinct on your list.

EDIT2: You need an equality comparer that compares ListItem's I believe.

You'll need to pass in a custom comparor that compares just the Value property of the ListItem.

var newList = newItems.Except(currentItems, new ListItemValueComparer());

And the custom equality comparer is here...

class ListItemValueComparer : IEqualityComparer<ListItem>
{
    public bool Equals(ListItem x, ListItem y)
    {
        return x.Value.Equals(y.Value);
    }

    public int GetHashCode(ListItem obj)
    {
        return obj.Value.GetHashCode();
    }
}
Kevin
  • 4,586
  • 23
  • 35
  • Is there no way to just look at just the Value of the of the items in list since the Text is the only part of the list that contains description. Or is that something completely different? – Joe W Dec 09 '13 at 20:45
  • I've edited the custom comparer to accept a ListItem though I don't know exactly what you intend to pass into it. You can redefine the generic attribute to be whatever your list holds and it should work. If it doesn't give me the fully qualified type of the object in your list. – Kevin Dec 09 '13 at 20:59
  • This did accomplished exactly what I was trying to achieve. Thank you for your help, and your explaining of what was needed. – Joe W Dec 09 '13 at 21:58