0

Hi I have the following lists:

 var CustomerName = new List<Customer>();
 var DummyData = new List<Customer>();

How can I quickly check that DummyData is contained inside of CustomerName? Also performance is key as these lists might contain thousands of values.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
Elsid
  • 243
  • 2
  • 10
  • 25
  • 2
    Why does your question have a sql tag but is using lists for the two variables? – konkked Jun 09 '16 at 19:47
  • Possible duplicate of [Does .NET have a way to check if List a contains all items in List b?](http://stackoverflow.com/questions/1520642/does-net-have-a-way-to-check-if-list-a-contains-all-items-in-list-b) – Halfwarr Jun 09 '16 at 19:48

1 Answers1

5

Brute Force Method

Use linq all method against the DummyData variable O(N*K)

// If you override Equals and GetHashCode or are comparing by reference
DummyData.All(a=>CustomerName.Contains(a))

//If you compare by property
DummyData.All(a=>
               CustomerName.Any(b=>
                   a.FirstName==b.FirstName && 
                   a.LastName == b.LastName
                   //repeat to include checks for all properties
              )
          );

Using a HashSet

Put your results into a hashset and use linq's All method again checking if hashset contains items, takes N steps to build hashset and K steps to check, complexity is O(N+K)

var hs = new HashSet<Customer>(CustomerName);
DummyData.All(a=>hs.Contains(a));

You will need to override Equals And GetHashCode

If you haven't overriden these two yet you'll need to unless you want to compare properties and this prevents you from using the hash set method as well

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public override bool Equals(object obj)
    {
        var customer = obj as Customer;
        return customer != null && Equals(customer);
    }

    protected bool Equals(Customer other)
    {
        return string.Equals(FirstName, other.FirstName) && string.Equals(LastName, other.LastName);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((FirstName?.GetHashCode() ?? 0)*397) ^ (LastName?.GetHashCode() ?? 0);
        }
    }
}
konkked
  • 3,161
  • 14
  • 19
  • I would note that this uses _reference equality_ unless you're overridden `Equals` and `GetHashCode`. – D Stanley Jun 09 '16 at 19:54
  • Brute force doesn't work it returns false when I do a bool – Elsid Jun 09 '16 at 20:03
  • @Elsid did you override the Equals and GetHashCode method? You'll need to do that regardless for both examples provided – konkked Jun 09 '16 at 20:08
  • Is there a way to do it without overriding Equals? – Elsid Jun 09 '16 at 20:09
  • @Konkked there is no first name or last name, the list just contains the values returned to it. Example: CustomerName(0)="ABC Company" ect. ect. – Elsid Jun 09 '16 at 20:18
  • @Elsid what is `Customer` then? Do you have a list of `Customer` or a list of `string`? If you put the class in your answer it will be easier for me to give you an exact answer – konkked Jun 09 '16 at 20:22
  • I have a field Name, when I ran it with Name bool contains returned false. – Elsid Jun 09 '16 at 20:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/114280/discussion-between-konkked-and-elsid). – konkked Jun 09 '16 at 20:25