score:1

Accepted answer

the best i can think of is :

a) create dictionary and use its fast lookups

b) use linq .where method with .containskey() on this dictionary which internally uses hashtable and performs quick lookups.

this should reduce search complexity to almost o(1) rather than o(n) ro worse (when we use linq .where() with .any() or .contains() and that leads to nested loops).

from msdn page :

the dictionary generic class provides a mapping from a set of keys to a set of values. each addition to the dictionary consists of a value and its associated key. retrieving a value by using its key is very fast, close to o(1), because the dictionary class is implemented as a hash table.

so what we can do is :

dictionary<string, string> dict = listproviderkeys.todictionary(s => s);

var newlist = secondlist.where(e => !dict.containskey(e.providerkey)).tolist();

here is a very simple, short, but complete example illustrating it and also testing its performance :

class person
{
    public int id { get; set; }        
}

class program
{
    static void main(string[] args)
    {
        list<int> ints = new list<int>();
        list<person> people = new list<person>(1000);

        for (int i = 0; i < 7500; i++)
        {
            ints.add(i);
            ints.add(15000 - i - 1);
        }

        for (int i = 0; i < 45000; i++)
            people.add(new person() { id = i });

        stopwatch s = new stopwatch();

        s.start();

        // code a (feel free to uncomment it)         
        //dictionary<int, int> dict = ints.todictionary(p => p);

        //list<person> newlist = people.where(p => !dict.containskey(p.id)).tolist();

        // code b
        list<person> newlist = people.where(p => !ints.contains(p.id)).tolist();

        s.stop();

        console.writeline(s.elapsedmilliseconds);
        console.writeline("number of elements " + newlist.count);

        console.readkey();
    }

on release mode results are :

both code a & code b outputs 30 000 elements but :

it took more than 2000 ms with code b and only 5 ms with code a

score:-2

i believe this will work:

list<changessummary> exceptionlist = secondlist.
where(x => !listproviderkeys.any(key => x.providerkey == key)).tolist();

score:-1

i think in this case simple where would be easier and more readable to apply.

var first = new list<string> { "a" };
var second = new list<changessummary>()
{
    new changessummary() { providerkey = "a" },
    new changessummary() { providerkey = "b" }
};

var result = second.where(item => !first.contains(item.providerkey));

// result
//    .tolist()
//    .foreach(item => console.writeline(item.providerkey));

score:0

 public class programm
    {
        public static void main()
        {
             list<changessummary>  summaries = new list<changessummary>();

             summaries.add(new changessummary()
             {
                 fieldname = "1",
                 providerkey = "test1",
             });

             summaries.add(new changessummary()
             {
                 fieldname = "2",
                 providerkey = "test2",
             });

             summaries.add(new changessummary()
             {
                 fieldname = "3",
                 providerkey = "test3",
             });

            list<string> listproviderkeys = new list<string>();

            listproviderkeys.add("test1");
            listproviderkeys.add("test3");

            var res = summaries.where(x => !listproviderkeys.contains(x.providerkey));


            res.tolist().foreach(x => console.writeline(x.providerkey));

            console.readline();
        }
    }

    public class changessummary
    {
        public string tablename { get; set; }
        public string providerkey { get; set; }
        public string provideradrskey { get; set; }
        public string providerspecialtykey { get; set; }
        public string fieldname { get; set; }
    }

Related Query

More Query from same tag